unsorted
unsorted

Reputation: 3274

push_back(this) pushes wrong pointer onto vector

I have a vector of UnderlyingClass pointers stored in another object, and inside a method in UnderlyingClass I want to add the "this" pointer to the end of that vector. When I look at the contents of the vector immediately after the push_back call, the wrong pointer is in there. What could be going wrong?

cout << "this: " << this << endl;
aTextBox.callbacks.push_back(this); 
cout << "size is " << aTextBox.callbacks.size() << endl;
cout << "size-1: " << aTextBox.callbacks[aTextBox.callbacks.size()-1] << endl;
cout << "back: " << aTextBox.callbacks.back() << endl;
cout << "0: " << aTextBox.callbacks[0] << endl;
cout << "this: " << this << endl;
cout << "text box ptr: " << &aTextBox << endl;
cout << "text box callbacks ptr: " << &(aTextBox.callbacks) << endl;

Here's the output:

this: 0x11038f70
size is 1
size-1: 0x11038fa8
back: 0x11038fa8
0: 0x11038fa8
this: 0x11038f70
text box ptr: 0x11039070
text box callbacks ptr: 0x11039098

By the way, callbacks is a vector of WebCallback pointers, and UnderlyingClass implements WebCallback:

std::vector<WebCallback*> callbacks;


class UnderlyingClass
    :public WebCallback 

Copied from comments: (see Answer below)

output:

this: 0x6359f70 
size is 1 
size-1: 0x6359fa8 
back: 0x6359fa8 
0: 0x6359fa8 
this: 0x6359f70 
WebCallback This: 0x6359fa8 
text box ptr: 0x635a070 
text box callbacks ptr: 0x635a098 

okay, so that explains why the pointers don't match up.

My real question, then, is this:

how do I get the correct version of a method to be called? Specifically, WebCallback stipulates that a function onWebCommand() be implemented, and right now callbacks[0]->onWebCommand() is not causing the onWebCommand() that I wrote in UnderlyingClass to be executed.

Upvotes: 3

Views: 906

Answers (2)

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 506897

This can happen with multiple inheritance, if your layout looks like this:

class UnderlyingBase {
  char d[56];
};

class UnderlyingClass
    :public UnderlyingBase, 
     public WebCallback {

};

Then the layout can be like this, for each object involved. The last one is the complete object containing the first two ones as base-class sub-objects, and that you take the pointer of, and which will be converted to WebCallback*.

[UnderlyingBase]
 > char[56]: 56 bytes, offset 0x0

[WebCallback]
 > unknown:  x bytes, offset 0x0

[UnderlyingClass]
 > [UnderlyingBase]: 56 bytes (0x38 hex), offset 0x0
 > [WebCallback]:    x  bytes, offset 0x38

Now since your vector contains WebCallback*, the compiler adjusts the pointer to point to the WebCallback sub-object, while when it would point to UnderlyingClass or UnderlyingBase, it would start 0x38 (56) bytes earlier.

Upvotes: 8

Loki Astari
Loki Astari

Reputation: 264361

Add this to your print out:

cout << "this: " << this << endl;
cout << "WebCallback This: " << dynamic_cast<WebCallback*>(this) << endl;

I bet this is what you are looking for.

Upvotes: 3

Related Questions