1

Hence we have the classical diamond problem and int's solution:

class A
{
public:
    A()
    {
        std::cout << "A c'tor" << std::endl;
    }
    void f()
    {
        std::cout << "A::f()" << std::endl;
    }
};

class B :virtual public A{};

class C :virtual public A{};

class D : public B, public C{};

How does the compiler handles this, so it creates only one instance of A? Please answer as specific as you can.

Eduard Rostomyan
  • 7,050
  • 2
  • 37
  • 76

1 Answers1

2

Standard doesn't specify how should compiler handle that, but usually (AFAIK gcc and MSVC), it's implemented the way I described below.

When class inherits normally, it will contain all of base class members

When class inherits virtually, it will (instead of whole class) contain pointer to where that base class resides, virtual base class shall reside in most derived object:

struct A
{
   int i;
};

struct B: virtual A{};

struct C: B{};



int someFunction()
{
    /* b internally contains pointer that points to it's (virtual)base class , 
    in this case B itself is most derived object so it points to base class
    which is stored somewhere inside B */

    B b;


    /* now subobject B (which is stored inside C) contains pointer that
      ,again points to it's (virtual) base class 
      ,but that class now resides in most derived object which is C */

    C c;
}

Extra points:

Can you figure out where is the error?

struct A
{
    std::string message;

    A(std::string parameter): message(parameter) {}

};

struct B: virtual A
{
    B(std::string parameter): A(parameter) {}
};

struct C: B
{
    C(){}
};
PcAF
  • 1,975
  • 12
  • 20
  • "_it will (instead of whole class) contain pointer_" or not. It's an implementation detail. Not all compilers use internal pointers. – curiousguy Jun 05 '16 at 09:05
  • @curiousguy Yes, you're right, standard specifies only *What shall happen*, not *How shall it happen*. I tried to answer briefly. I've added som lines to the answer. – PcAF Jun 06 '16 at 08:38
  • I am *not* sure the internal pointer implementation is the "usual", or most common one, I know it's what MSVC does, so compilers intended to generate compatible code (at the binary level) must follow this scheme, and most Windows compilers probably will do that. However it wastes some room in the object. – curiousguy Jun 07 '16 at 01:31
  • @curiousguy I've tested it with `gcc` and it seems that it also uses *internal pointer*, more specifically `virtual pointer` pointing to `virtual table`. It takes some place in object but it's not so bad since the same (virtual) pointer is used to resolve virtual functions. – PcAF Jun 07 '16 at 11:53
  • I don't call these "internal pointers" but "vptr" (or vtable pointers). – curiousguy Jun 07 '16 at 12:28