4

How does the conversion between derived and base class internally occurs and how does compiler knows or does it store the size of object?

For example in the following:

class A
{
public:
 A():x(2){};
private:
 int x;
};

class B : public A
{
public:
 B():A(),y(5){};
private:
 int y;
};

class C : public B
{
public:
 C():B(),z(9){};
private:
 int z;
};

int main()
{
   C *CObj = new C;
   B *pB = static_cast<B*>(CObj);
   delete CObj;
}

Edit: It must have been this:

B BObj = static_cast<B>(*CObj);
user963241
  • 6,758
  • 19
  • 65
  • 93
  • 2
    This is a complex question, and I've seen it before (in various forms) on Stack Overflow. I've never really seen an answer that does the question justice. I don't think it can be done on Stack Overflow as the real answer is just too big. Of course, it's easy to say "It's implementation defined, there is no answer.", and that's true. But it's also true that most implementations do it similarly, and explaining how even one implementation actually worked would be very enlightening to people who ask this question. – Omnifarious Sep 12 '10 at 08:53
  • And also, the one person who answered is correct, the `static_cast` is totally superfluous, and in fact should be removed as it's pretty misleading. It should read `B *pB = CObj;`. – Omnifarious Sep 12 '10 at 08:54
  • Lastly, here are a list of related questions: http://stackoverflow.com/questions/1321062/object-layout-in-case-of-virtual-functions-and-multiple-inheritance http://stackoverflow.com/questions/2006504/c-data-alignment-member-order-inheritance http://stackoverflow.com/questions/396327/question-on-multiple-inheritance-virtual-base-classes-and-object-size-in-c http://stackoverflow.com/questions/1632600/memory-layout-c-objects and a link to a good answer not on Stack Overflow: http://www.openrce.org/articles/full_view/23 – Omnifarious Sep 12 '10 at 09:07
  • The code you posit after __Edit__ is doing something very strange and probably wrong. Also, the `static_cast` is still completely superfluous. Now if your code read `B *pB = new C; C *CObj = static_cast(pB); delete CObj;` then the `static_cast` would not be superfluous. – Omnifarious Sep 12 '10 at 09:19

5 Answers5

5

You don't have any "derived to base" conversion in your code. What you have in your code is a pointer-to-derived to pointer-to-base conversion. (This conversion does not require any explicit cast, BTW)

B *pB = CObj; // no need for the cast

In order to perform the pointer conversion, there's no need to know the size of the object. So, it is not clear where your reference to "size of the object" comes from.

In fact, in the typical implementation the above conversion for single-inheritance hierarchy of non-polymorphic classes is purely conceptual. I.e. the compiler does not do anything besides simply copying the numerical value of the derived pointer into the base pointer. No extra information is needed to perform this operation. No size, no nothing.

In more complicated situations (like multiple inheritance), the compiler might indeed have to generate code that would adjust the value of the pointer. And it will indeed need to know the sizes of the objects involved. But the sizes involved are always compile-time ones, i.e. they are compile-time constants, meaning that the compiler does immediately know them.

In even more complicated cases, like virtual inheritance, this conversion is normally supported by run-time structures implicitly built into the object, which will include everything deemed necessary. Run-time size of the object might be included as well, if the implementation chooses to do so.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • You do if you have template specialized methods for half a dozen or so test cases. In which case you need to know the specific type of the method specialization. – mwpowellhtx Nov 29 '18 at 05:57
1

Note that you don't need the static_cast here; it's perfectly legal to "up-cast" a pointer-to-derived-class to a pointer-to-parent-class.

In this example, there is no conversion going on. The pointer value stays the same (i.e. under the hood, CObj and pB point at the same memory, though things get more complex with multiple inheritance). The compiler organises the members of B and C objects in memory so that everything just works. As we're dealing with pointers, the size of the object doesn't matter (that was only relevant when you created a new C).

If you had any virtual methods, then we could talk about vtables and vptrs (http://en.wikipedia.org/wiki/Vtable).

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
1

A derived class object has base class subobjects. Specifically the Standard says in 10.3

"The order in which the base class subobjects are allocated in the most derived object (1.8) is unspecified"

This means that even though many a times, the base subobject could be right at the beginning of the derived object, it is not necessary. Hence the conversion from Derived* to Base* is completely unspecified and is probably left as a degree of latitude to compiler developers.

I would say that it is important to know the rules of the language and the reason behind the same, rather than worry about how compiler implements them. As an example, I have seen far too many discussions on VTABLE and VPTR which is a compiler specific implementation to achieve dynamic binding. Instead it helps to know about the concept of 'unique final overrider' that is enough to understand the concept of virtual functions and dynamic binding. The point is to focus on 'what' rather than 'how', because 'how' most of the times is not required. I say most of the times because in some cases it helps. An example is to understand the concept of 'pointer to members'. It helps to know that it is usually implemented in some form of 'offset' rather than being a regular pointer.

Chubsdad
  • 24,777
  • 4
  • 73
  • 129
0

How does the conversion between derived and base class internally occurs

Implementation defined.
Imposable to answer unless you tell us which compiler you are using.
But generally not worth knowing or worrying about (unless you are writing a compiler).

and how does compiler knows [editor] size of the object

The compiler knows the size (It has worked out the size of C during compilation).

or does it store the size of object?

The object does not need to know the size and thus it is not stored as part of the class.
The runtime memory management (used via new) may need to know (but it is implementation defined) so that it can correctly release the memory (but anything it stores will not be stroed in the object).

Martin York
  • 257,169
  • 86
  • 333
  • 562
-5

If you have ever done any C, the answer would come from itself.

A memory allocator doesn't care at all about what it is storing. It just have to know what memory ranges has been allocated. It doesn't see the difference between a C and an int[4]. It just have to know how to free the memory range that starts at the given pointer.

BatchyX
  • 4,986
  • 2
  • 18
  • 17
  • 4
    -1 How does that answer relate to the question? How would experience with C help someone understand the conversion of pointers in a class hierarchy in C++? – Björn Pollex Sep 12 '10 at 08:35
  • To me there is two question : "How does the conversion between derived and base class internally occurs" and "how does compiler knows or does it store the size of object?". I'm answering the second question : how does the compiler know the size of the object that it must delete. Or at least that what i understood. Maybe xor can clarify – BatchyX Sep 12 '10 at 09:38