Archived

This topic is now archived and is closed to further replies.

Anomaly_E

this* and inheritance

Recommended Posts

Hi, I have run into a spot of trouble with my this pointers and wonder if anyone here can help me out... I want to create a class which inherits a function from another class. The function needs to know what size the current object is, so it uses "sizeof(*this)". When the function then is used in the derived object I also want the size of the derived object, but the size I get is the size of the base class where the function is defined... I guess this is the way things are but is there any other way to do what I want without overloading the function or in any other ways change every derived class. The reason behind this is that I want the function to be able to handle all objects as long as they are derived from the base class. All data needed is in the base class except the size of the inherited object which I don''t see how to get as I don''t know what objects might be used in the future. Here is some code to demonstrate what I mean: *************************************************************** #include <iostream> using namespace std; class ca{ public: ca(){} ~ca(){} void getSize(){cout << sizeof(*this) << " ";} int a; long b; }; class cb : public ca{ public: cb(){} ~cb(){} long c; }; void main(){ ca* a = new ca(); cb* b = new cb(); // or even better: ca* = new cb(); // Both these return the size of the class ca... // but I want the size of cb too! a->getSize(); b->getSize(); delete a; delete b; } *************************************************************** End of Code I use MSVCPP6... Regards Anomaly_E

Share this post


Link to post
Share on other sites
I would suggest you to check the virtual keyword.
What happens is that the method GetSize is declared in your base class but will only return the size of class ca. To have the size of cb, you need to declare virtual the method GetSize in ca and create a virtual method GetSize in cb.
I let you experiment with it.
Have fun.
Red Ghost

Share this post


Link to post
Share on other sites
Expanding on what he said, and sticking with your examlpe...


  
#include <iostream>

using namespace std;

class ca{
public:
ca(){}
~ca(){}
virtual void getSize(){cout << sizeof(*this) << " ";}
int a;
long b;
};

class cb : public ca{
public:
cb(){}
void getSize(){cout << sizeof(*this) << " ";}
~cb(){}
long c;
};

void main(){
ca* a = new ca();
cb* b = new cb(); // or even better: ca* = new cb();


// Both these return the size of the class ca...

// but I want the size of cb too!

a->getSize();
b->getSize();

delete a;
delete b;
}


Now it works . That was a basic example of virtual functions. Hope it helps.

Billy - BillyB@mrsnj.com

Share this post


Link to post
Share on other sites
Thanks for the feedback but my problem is still there... I don''t want to do any "sizeof" in the derived classes... in my real code the function that needs "sizeof" is big and ugly... and I want it to be easy for other people to add their own derived classes. In the ideal case you just derive your class from the base class and do nothing more...

As a little background information, the function(s) in question are some low-level memory managment that handles convertion to/from c-compatible char*, that''s why I need the size... please keep shooting :-)

Share this post


Link to post
Share on other sites
quote:
Original post by Anomaly_E
Thanks for the feedback but my problem is still there... I don''t want to do any "sizeof" in the derived classes...

This has nothing to do with where you call sizeof. sizeof is an operator, and is invoked differently for each class. It returns the number of bytes reserved for objects of a particular class.

For inheritance hierarchies, it is important to make member functions and the destructor virtual. This is what allows for polymorphic dispatch, and affects the size of the internal representation of the class.

quote:

in my real code the function that needs "sizeof" is big and ugly... and I want it to be easy for other people to add their own derived classes. In the ideal case you just derive your class from the base class and do nothing more...

If the classes in question are complex, add a size() method. It''s much more reliable, particularly if dynamically allocated data is involved (sizeof will return the sie of a pointer to data rather than the size of the data pointed to).

Share this post


Link to post
Share on other sites
quote:
Original post by Oluseyi
For inheritance hierarchies, it is important to make member functions and the destructor virtual. This is what allows for polymorphic dispatch, and affects the size of the internal representation of the class.



Hm, the destructors too you say... Now I tried to declare all destructors and the function as virtual in my original example but it still doesn't work... I didn't add the virtual function to the derived class as I don't want it there... but I don't know if I understood that last bit correctly... were you sugesting that it is possible to call the base class function containing sizeof(*this) through a derived object with the desired result without altering the derived class...?

otherwise I guess it is acceptable to let users make there own size functions as you said... that is perhaps something to fall back on after all...


[edited by - Anomaly_E on October 2, 2002 2:14:34 PM]

[edited by - Anomaly_E on October 2, 2002 2:17:07 PM]

[edited by - Anomaly_E on October 2, 2002 2:19:29 PM]

Share this post


Link to post
Share on other sites
Short answer? You can''t do what you want to do without adding a virtual size_of() or getSize() function.

Period.

The language doesn''t work that way.

What happens is this:

when you do *this, you''re dereferencing the this pointer, which is a pointer to the class that the method is being called on.

Now, what *this returns is dependent on where it is called. *this has absolutely nothing to do with the vtable, which is where all polymorphic behavior is implemented. In other words, you can''t have polymorphism without the virtual table (vtbl).

If you call *this in a method of MyClass, you''ll get a const reference to an instance of MyClass. See?

So, since sizeof() is determined at compile time, if you call sizeof(*this) inside a method of MyClass, even if that method is being called on an instance of MyDerivedClass, you''ll get the size of MyClass.

The solution? Add this function to every derived class (and make it virtual in the base):

virtual size_t size_of() { return sizeof(*this); } 


That way, it''s in the vtbl, and will be dispatched to the correct member function when called, regardless of where (as long as you call it from a pointer or reference type).

Share this post


Link to post
Share on other sites