1

Hey I'm trying to understand how size of class work when I'm using inheritance, so I wrote this code:

class AA 
{
public :
    int a;
    virtual int getSize() {return sizeof(*this);}   
};

class BB : public AA
{
public :
    int b;  
    virtual int getSize2() {return sizeof(*this);}
};

int _tmain(int argc, _TCHAR* argv[])
{
    AA aa;
    BB bb;
    std::cout << "Class AA : " << aa.getSize() << std::endl;
    std::cout << "Class BB : " << bb.getSize() << std::endl;
    std::cout << "Class BB : " << bb.getSize2() << std::endl;
}

The output of this code is :

Class AA : 8
Class BB : 8
Class BB : 12

My question is : why the second output return the size of AA instead than returning the size of BB? bb it's BB type, so I was expecting 12 instead of 8?

1
  • "why is the result blah" is almost always a bad question; a better question would be "My intent was to blah, according to my understanding blah does blah, and then blah follows, but it does not work in practice, how is my reasoning about blah not correct?" Commented Aug 22, 2017 at 17:44

3 Answers 3

3
virtual int getSize() {return sizeof(*this);}

Although we don't always think of it as such, sizeof computes its value at compile-time, not run-time. So you might as well think of this function as looking like this:

virtual int getSize() {return 8;}

Which you would obviously not expect to change when inherited into another class.

The way to ensure that derived classes return the correct value is to make sure they override this function with the size of their respective class.

Sign up to request clarification or add additional context in comments.

1 Comment

This is IMO the best answer which directly addresses OP's issue - sizeof computes its value at compile-time.
2
  1. Classes have no size. Objects have sizes.

  2. getSize() only knows the size of objects of type A.

  3. getSize2() only knows the size of objects of type B.

3 Comments

Types have sizes. sizeof(AA) would be legitimate.
@FrançoisAndrieux: That just means "size of an object of type AA". Doesn't make the type have a size.
@Deduplicator Sure, I'll grant you that "size of an object T" is equivalent to "size of type T" when talking about c++, but I won't grant you that the second formulation is incorrect. In practice, nobody competent would be confused by the statement "int has a size of 4 on my platform" which is more concise than "variables of type int have a size of 4 on my platform". When describing a type, the size is a ubiquitous characteristic, rather or not it's explicitly recognized by the standard. Correcting someone for using the first formulation is, I believe, needlessly pedantic.
2

You never override getSize() in BB so bb.getSize() calls AA::getSize() and returns the size of bb's AA part. To get the behavior you expected you need to add

int getSize() {return sizeof(*this);}

in BB.


To get into more detail when you do

bb.getSize()

That gets translated to BB::getSzie(bb). So we call BB's function getSzie() and we pass it the object to use. Since BB doesn't override getSize() the function that is chosen is AA::getSize(). So we pass the bb to AA's function. AA's version of the function takes a AA& so in the function this has the type AA even though we gave it a BB. That is why it prints the size of AA. You have to add the override into BB so that when it call the function the static type of this is BB and then you can get BB's size.

4 Comments

you answer does not explain why. The answer I linked to (as I believe this one is be direct duplicate of) gives much more information OP looks for.
@MarcinOrlowski How do I not explain why bb.getSize() returns the same as aa.getSize(). I don't see how your question that you suggest as a dupe is a dupe for this question.
@JesperJuhl "The reason being that the function operates on an instance of AA." - That's not true, the type of *this is still BB, and if you where to call virtual function from getSize(), you would call BB's override, the real reason is that sizeof() is a compile-time value, and at compile time decltype(*this) inside getSize() is AA&.
@FrançoisAndrieux Added a more in-depth explanation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.