3

Having multiple inheritance

class A{};
class B{};

class C: public A, public B{};

what happens when i do

C *c = new C;
A *a = c;  
B *b = c;

A *a1 = new C;
B *b1 = new C;

What happens with first instance of C? Does assiging C to pointer of type A slice the object, so A points only to part of C that contains members of A? If so, how does it know when to top? If C contains A part and B part, and A part starts at offset 0 , how does it know which offset to stop?

Thanks for help.

Sean
  • 60,939
  • 11
  • 97
  • 136
Dingo
  • 331
  • 2
  • 3
  • 10
  • 5
    You're missing a lot of semi-colons. – Mike Borkland May 16 '18 at 12:05
  • 2
    No slicing happens in your code. `A a = C()` would do slicing. – Jarod42 May 16 '18 at 12:05
  • Google "c++ adjustor thunks" to find hits that might be relevant to your specific compiler. – Hans Passant May 16 '18 at 12:07
  • Another good read is https://shaharmike.com/cpp/vtable-part1/, which discusss how the C++ vtables are laid out by the GCC compiler. – Paul Belanger May 16 '18 at 12:10
  • thunks and vtables don't apply to the code shown. The compiler simply adds a constant offset when implicitly converting `C*` to `B*`. – aschepler May 16 '18 at 12:11
  • @aschepler: And with current code, offset of 0 is valid (thanks to Empty Base class Optimization). – Jarod42 May 16 '18 at 12:12
  • Possible duplicate of [Multiple inheritance and pointer implementation](https://stackoverflow.com/questions/16185945/multiple-inheritance-and-pointer-implementation) – Piotr Siupa May 16 '18 at 12:14
  • Possible duplicate of [How is C++'s multiple inheritance implemented?](https://stackoverflow.com/questions/1002503/how-is-cs-multiple-inheritance-implemented) – YesThatIsMyName May 16 '18 at 12:15
  • Recommended reading: Stroustrup wrote a paper in 1989 [Multiple Inheritance in C++](https://www.usenix.org/legacy/publications/compsystems/1989/fall_stroustrup.pdf) that gives a very readable explanation of what a typical implementation does in this case and how to deal with the various interesting problems that arise. – ComicSansMS May 16 '18 at 12:56

3 Answers3

3

C, as a child of both, is a A and is a B. So, when you upcast a pointer no slicing happens (why would it anyway?) but the pointer points to an appropriate portion of the object. A standard diagram would be smth. like

 c -> +++++++++++++++++++++
      +        C          +
 a -> + +++++++++++++++++ +
      + +      A        + +
      + +++++++++++++++++ +
      +                   +
 b -> + +++++++++++++++++ +
      + +      B        + +
      + +++++++++++++++++ +
      +                   +
      +  C's own members  +
      +                   +
      +++++++++++++++++++++

Both a and b point to the respective subobjects.

How does it know? — Well, the compiler creates memory layouts, it definitely knows what virtual addresses should pointers be assigned to, and how up/downcasting amounts to a pointer offset.

Note that when you use a plain pointer-to-base as a sole (and owning) reference to object, you should declare base's destructor virtual, otherwise you won't be able to properly destroy the object.

bipll
  • 11,747
  • 1
  • 18
  • 32
0

First C++ requires all instructions to be ended with a semicolon (;).

Now for your questions:

What happens with first instance of C?

Nothing. A * a = c; actually initializes a A * pointer pointing to the dynamically allocated *c C object. It is a valid pointer conversion because C is a subclass of A. In fact this is just the basics for polymorphism.

Does assiging C to pointer of type A slice the object, so A points only to part of C that contains members of A?

No slicing occurs when you convert pointers. A a1 = *(static_cast<A *>(c)); would indeed generate a sliced copy containing only the A part.

If so, how does it know when to top?

How is an implementation detail. Compilers can do that because it is specified in standard. Common implementations use offsets in object addresses.

If C contains A part and B part, and A part starts at offset 0 , how does it know which offset to stop?

Here again it is an implementation detail. But for common implementations the A part ends at start offset + sizeof(A).

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
0

Does assiging C to pointer of type A slice the object

No. Initializing (or assigning, but assignment is not what your code does) a pointer has no effect on the pointed object.

so A points only to part of C that contains members of A?

This doesn't follow from slicing, since that doesn't happen, but yes, a (which is the name of the pointer variable, not A) indeed points to the A sub-object within the C object. The A object contains only its own members.

how does it know which offset to stop?

The compiler knows how big an object needs to be, and it decides the exact size of all defined types. Since it is the compiler that made the decision, of course it knows what it decided.

eerorika
  • 232,697
  • 12
  • 197
  • 326