<p>I want to know what a "<em>virtual base class</em>" is and what it means.</p>

<p>Let me show an example:</p>

<pre><code>class Foo
{
public:
    void DoSomething() { /* ... */ }
};

class Bar : public virtual Foo
{
public:
    void DoSpecific() { /* ... */ }
};
</code></pre>

[{'answer_id': 21598, 'author': 'wilhelmtell', 'author_id': 456, 'author_profile': 'https://Stackoverflow.com/users/456', 'pm_score': 1, 'selected': False, 'text': '<p>It means a call to a virtual function will be forwarded to the "right" class.</p>\n\n<p>C++ <a href="https://isocpp.org/wiki/faq/multiple-inheritance" rel="nofollow noreferrer">FAQ Lite</a> FTW.</p>\n\n<p>In short, it is often used in multiple-inheritance scenarios, where a "diamond" hierarchy is formed.  Virtual inheritance will then break the ambiguity created in the bottom class, when you call function in that class and the function needs to be resolved to either class D1 or D2 above that bottom class.  See the <a href="https://isocpp.org/wiki/faq/multiple-inheritance#virtual-inheritance-where" rel="nofollow noreferrer">FAQ item</a> for a diagram and details.</p>\n\n<p>It is also used in <em>sister delegation</em>, a powerful feature (though not for the faint of heart).  See <a href="https://isocpp.org/wiki/faq/multiple-inheritance#mi-delegate-to-sister" rel="nofollow noreferrer">this</a> FAQ.</p>\n\n<p>Also see Item 40 in Effective C++ 3rd edition (43 in 2nd edition).</p>\n'}, {'answer_id': 21607, 'author': 'OJ.', 'author_id': 611, 'author_profile': 'https://Stackoverflow.com/users/611', 'pm_score': 10, 'selected': True, 'text': '<p>Virtual base classes, used in virtual inheritance, is a way of preventing multiple "instances" of a given class appearing in an inheritance hierarchy when using multiple inheritance.</p>\n\n<p>Consider the following scenario:</p>\n\n<pre><code>class A { public: void Foo() {} };\nclass B : public A {};\nclass C : public A {};\nclass D : public B, public C {};\n</code></pre>\n\n<p>The above class hierarchy results in the "dreaded diamond" which looks like this:</p>\n\n<pre><code>  A\n / \\\nB   C\n \\ /\n  D\n</code></pre>\n\n<p>An instance of D will be made up of B, which includes A, and C which also includes A. So you have two "instances" (for want of a better expression) of A.</p>\n\n<p>When you have this scenario, you have the possibility of ambiguity. What happens when you do this:</p>\n\n<pre><code>D d;\nd.Foo(); // is this B\'s Foo() or C\'s Foo() ??\n</code></pre>\n\n<p>Virtual inheritance is there to solve this problem. When you specify virtual when inheriting your classes, you\'re telling the compiler that you only want a single instance.</p>\n\n<pre><code>class A { public: void Foo() {} };\nclass B : public virtual A {};\nclass C : public virtual A {};\nclass D : public B, public C {};\n</code></pre>\n\n<p>This means that there is only one "instance" of A included in the hierarchy. Hence</p>\n\n<pre><code>D d;\nd.Foo(); // no longer ambiguous\n</code></pre>\n\n<p>This is a mini summary. For more information, have a read of <a href="http://en.wikipedia.org/wiki/Virtual_inheritance" rel="noreferrer">this</a> and <a href="https://isocpp.org/wiki/faq/multiple-inheritance" rel="noreferrer">this</a>. A good example is also available <a href="http://www.learncpp.com/cpp-tutorial/118-virtual-base-classes/" rel="noreferrer">here</a>.</p>\n'}, {'answer_id': 21612, 'author': 'wilhelmtell', 'author_id': 456, 'author_profile': 'https://Stackoverflow.com/users/456', 'pm_score': 3, 'selected': False, 'text': '<blockquote>\n  <p>A virtual base class is a class that\n  cannot be instantiated : you cannot\n  create direct object out of it.</p>\n</blockquote>\n\n<p>I think you are confusing two very different things.  Virtual inheritance is not the same thing as an abstract class.  Virtual inheritance modifies the behaviour of function calls;  sometimes it resolves function calls that otherwise would be ambiguous, sometimes it defers function call handling to a class other than that one would expect in a non-virtual inheritance.</p>\n'}, {'answer_id': 21613, 'author': 'Baltimark', 'author_id': 1179, 'author_profile': 'https://Stackoverflow.com/users/1179', 'pm_score': 1, 'selected': False, 'text': "<p>You're being a little confusing. I dont' know if you're mixing up some concepts.</p>\n\n<p>You don't have a virtual base class in your OP. You just have a base class. </p>\n\n<p>You did virtual inheritance. This is usually used in multiple inheritance so that multiple derived classes use the members of the base class without reproducing them.</p>\n\n<p>A base class with a pure virtual function is not be instantiated. this requires the syntax that Paul gets at. It is typically used so that derived classes must define those functions. </p>\n\n<p>I don't want to explain any more about this because I don't totally get what you're asking. </p>\n"}, {'answer_id': 21616, 'author': 'bradtgmurray', 'author_id': 1546, 'author_profile': 'https://Stackoverflow.com/users/1546', 'pm_score': 0, 'selected': False, 'text': '<p>Virtual classes are <strong>not</strong> the same as virtual inheritance. Virtual classes you cannot instantiate, virtual inheritance is something else entirely.</p>\n\n<p>Wikipedia describes it better than I can. <a href="http://en.wikipedia.org/wiki/Virtual_inheritance" rel="nofollow noreferrer">http://en.wikipedia.org/wiki/Virtual_inheritance</a></p>\n'}, {'answer_id': 21629, 'author': 'wilhelmtell', 'author_id': 456, 'author_profile': 'https://Stackoverflow.com/users/456', 'pm_score': 3, 'selected': False, 'text': "<p>I'd like to add to OJ's kind clarifications.</p>\n\n<p>Virtual inheritance doesn't come without a price.  Like with all things virtual, you get a performance hit.  There is a way around this performance hit that is possibly less elegant.</p>\n\n<p>Instead of breaking the diamond by deriving virtually, you can add another layer to the diamond, to get something like this:</p>\n\n<pre><code>   B\n  / \\\nD11 D12\n |   |\nD21 D22\n \\   /\n  DD\n</code></pre>\n\n<p>None of the classes inherit virtually, all inherit publicly.  Classes D21 and D22 will then hide virtual function f() which is ambiguous for DD, perhaps by declaring the function private.  They'd each define a wrapper function, f1() and f2() respectively, each calling class-local (private) f(), thus resolving conflicts.  Class DD calls f1() if it wants D11::f() and f2() if it wants D12::f().  If you define the wrappers inline you'll probably get about zero overhead.</p>\n\n<p>Of course, if you can change D11 and D12 then you can do the same trick inside these classes, but often that is not the case.</p>\n"}, {'answer_id': 112474, 'author': 'paercebal', 'author_id': 14089, 'author_profile': 'https://Stackoverflow.com/users/14089', 'pm_score': 8, 'selected': False, 'text': "<h2>About the memory layout</h2>\n<p>As a side note, the problem with the Dreaded Diamond is that the base class is present multiple times. So with regular inheritance, you believe you have:</p>\n<pre><code>  A\n / \\\nB   C\n \\ /\n  D\n</code></pre>\n<p>But in the memory layout, you have:</p>\n<pre><code>A   A\n|   |\nB   C\n \\ /\n  D\n</code></pre>\n<p>This explain why when call <code>D::foo()</code>, you have an ambiguity problem. But the <strong>real</strong> problem comes when you want to use a member variable of <code>A</code>. For example, let's say we have:</p>\n<pre><code>class A\n{\n    public :\n       foo() ;\n       int m_iValue ;\n} ;\n</code></pre>\n<p>When you'll try to access <code>m_iValue</code> from <code>D</code>, the compiler will protest, because in the hierarchy, it'll see two <code>m_iValue</code>, not one. And if you modify one, say, <code>B::m_iValue</code> (that is the <code>A::m_iValue</code> parent of <code>B</code>), <code>C::m_iValue</code> won't be modified (that is the <code>A::m_iValue</code> parent of <code>C</code>).</p>\n<p>This is where virtual inheritance comes handy, as with it, you'll get back to a true diamond layout, with not only one <code>foo()</code> method only, but also one and only one <code>m_iValue</code>.</p>\n<h2>What could go wrong?</h2>\n<p>Imagine:</p>\n<ul>\n<li><code>A</code> has some basic feature.</li>\n<li><code>B</code> adds to it some kind of cool array of data (for example)</li>\n<li><code>C</code> adds to it some cool feature like an observer pattern (for example, on <code>m_iValue</code>).</li>\n<li><code>D</code> inherits from <code>B</code> and <code>C</code>, and thus from <code>A</code>.</li>\n</ul>\n<p>With normal inheritance, modifying <code>m_iValue</code> from <code>D</code> is ambiguous and this must be resolved. Even if it is, there are two <code>m_iValues</code> inside <code>D</code>, so you'd better remember that and update the two at the same time.</p>\n<p>With virtual inheritance, modifying <code>m_iValue</code> from <code>D</code> is ok... But... Let's say that you have <code>D</code>. Through its <code>C</code> interface, you attached an observer. And through its <code>B</code> interface, you update the cool array, which has the side effect of directly changing <code>m_iValue</code>...</p>\n<p>As the change of <code>m_iValue</code> is done directly (without using a virtual accessor method), the observer &quot;listening&quot; through <code>C</code> won't be called, because the code implementing the listening is in <code>C</code>, and <code>B</code> doesn't know about it...</p>\n<h2>Conclusion</h2>\n<p>If you're having a diamond in your hierarchy, it means that you have 95% probability to have done something wrong with said hierarchy.</p>\n"}, {'answer_id': 112722, 'author': 'Luc Hermitte', 'author_id': 15934, 'author_profile': 'https://Stackoverflow.com/users/15934', 'pm_score': 3, 'selected': False, 'text': '<p>In addition to what has already been said about multiple and virtual inheritance(s), there is a very interesting article on Dr Dobb\'s Journal: <a href="http://www.ddj.com/cpp/184402074" rel="noreferrer">Multiple Inheritance Considered Useful</a></p>\n'}, {'answer_id': 991723, 'author': 'lenkite', 'author_id': 120959, 'author_profile': 'https://Stackoverflow.com/users/120959', 'pm_score': 5, 'selected': False, 'text': '<p>Explaining multiple-inheritance with virtual bases requires a knowledge of the C++ object model. And explaining the topic clearly is best done in an article and not in a comment box.</p>\n\n<p>The best, readable explanation I found that solved all my doubts on this subject was this article: <a href="https://web.archive.org/web/20160413064252/http://www.phpcompiler.org/articles/virtualinheritance.html" rel="noreferrer">http://www.phpcompiler.org/articles/virtualinheritance.html</a></p>\n\n<p>You really won\'t need to read anything else on the topic (unless you are a compiler writer) after reading that...</p>\n'}, {'answer_id': 41026159, 'author': 'Ciro Santilli OurBigBook.com', 'author_id': 895245, 'author_profile': 'https://Stackoverflow.com/users/895245', 'pm_score': 2, 'selected': False, 'text': '<p><strong>Diamond inheritance runnable usage example</strong></p>\n<p>This example shows how to use a virtual base class in the typical scenario: to solve diamond inheritance problems.</p>\n<p>Consider the following working example:</p>\n<p>main.cpp</p>\n<pre><code>#include &lt;cassert&gt;\n\nclass A {\n    public:\n        A(){}\n        A(int i) : i(i) {}\n        int i;\n        virtual int f() = 0;\n        virtual int g() = 0;\n        virtual int h() = 0;\n};\n\nclass B : public virtual A {\n    public:\n        B(int j) : j(j) {}\n        int j;\n        virtual int f() { return this-&gt;i + this-&gt;j; }\n};\n\nclass C : public virtual A {\n    public:\n        C(int k) : k(k) {}\n        int k;\n        virtual int g() { return this-&gt;i + this-&gt;k; }\n};\n\nclass D : public B, public C {\n    public:\n        D(int i, int j, int k) : A(i), B(j), C(k) {}\n        virtual int h() { return this-&gt;i + this-&gt;j + this-&gt;k; }\n};\n\nint main() {\n    D d = D(1, 2, 4);\n    assert(d.f() == 3);\n    assert(d.g() == 5);\n    assert(d.h() == 7);\n}\n</code></pre>\n<p>Compile and run:</p>\n<pre><code>g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp\n./main.out\n</code></pre>\n<p>If we remove the <code>virtual</code> into:</p>\n<pre><code>class B : public virtual A\n</code></pre>\n<p>we would get a wall of errors about GCC being unable to resolve D members and methods that were inherited twice via A:</p>\n<pre><code>main.cpp:27:7: warning: virtual base ‘A’ inaccessible in ‘D’ due to ambiguity [-Wextra]\n   27 | class D : public B, public C {\n      |       ^\nmain.cpp: In member function ‘virtual int D::h()’:\nmain.cpp:30:40: error: request for member ‘i’ is ambiguous\n   30 |         virtual int h() { return this-&gt;i + this-&gt;j + this-&gt;k; }\n      |                                        ^\nmain.cpp:7:13: note: candidates are: ‘int A::i’\n    7 |         int i;\n      |             ^\nmain.cpp:7:13: note:                 ‘int A::i’\nmain.cpp: In function ‘int main()’:\nmain.cpp:34:20: error: invalid cast to abstract class type ‘D’\n   34 |     D d = D(1, 2, 4);\n      |                    ^\nmain.cpp:27:7: note:   because the following virtual functions are pure within ‘D’:\n   27 | class D : public B, public C {\n      |       ^\nmain.cpp:8:21: note:    ‘virtual int A::f()’\n    8 |         virtual int f() = 0;\n      |                     ^\nmain.cpp:9:21: note:    ‘virtual int A::g()’\n    9 |         virtual int g() = 0;\n      |                     ^\nmain.cpp:34:7: error: cannot declare variable ‘d’ to be of abstract type ‘D’\n   34 |     D d = D(1, 2, 4);\n      |       ^\nIn file included from /usr/include/c++/9/cassert:44,\n                 from main.cpp:1:\nmain.cpp:35:14: error: request for member ‘f’ is ambiguous\n   35 |     assert(d.f() == 3);\n      |              ^\nmain.cpp:8:21: note: candidates are: ‘virtual int A::f()’\n    8 |         virtual int f() = 0;\n      |                     ^\nmain.cpp:17:21: note:                 ‘virtual int B::f()’\n   17 |         virtual int f() { return this-&gt;i + this-&gt;j; }\n      |                     ^\nIn file included from /usr/include/c++/9/cassert:44,\n                 from main.cpp:1:\nmain.cpp:36:14: error: request for member ‘g’ is ambiguous\n   36 |     assert(d.g() == 5);\n      |              ^\nmain.cpp:9:21: note: candidates are: ‘virtual int A::g()’\n    9 |         virtual int g() = 0;\n      |                     ^\nmain.cpp:24:21: note:                 ‘virtual int C::g()’\n   24 |         virtual int g() { return this-&gt;i + this-&gt;k; }\n      |                     ^\nmain.cpp:9:21: note:                 ‘virtual int A::g()’\n    9 |         virtual int g() = 0;\n      |                     ^\n./main.out\n</code></pre>\n<p>Tested on GCC 9.3.0, Ubuntu 20.04.</p>\n'}, {'answer_id': 62281777, 'author': 'Lewis Kelsey', 'author_id': 7194773, 'author_profile': 'https://Stackoverflow.com/users/7194773', 'pm_score': 2, 'selected': False, 'text': '<h2>Regular Inheritance</h2>\n<img src="https://i.stack.imgur.com/7ski1.png" width="200">\n<p>With typical 3 level non-diamond non-virtual-inheritance inheritance, when you instantiate a new most-derived-object, <code>new</code> is called and the size required for the object on the heap is resolved from the class type by the compiler and passed to new.</p>\n<p><code>new</code> has a signature:</p>\n<pre><code>_GLIBCXX_WEAK_DEFINITION void *\noperator new (std::size_t sz) _GLIBCXX_THROW (std::bad_alloc)\n</code></pre>\n<p>And makes a call to <code>malloc</code>, returning the void pointer</p>\n<p>This address is then passed to the constructor of the most derived object, which will immediately call the middle constructor and then the middle constructor will immediately call the base constructor. The base then stores a pointer to its virtual table at the start of the object and then its attributes after it. This then returns to the middle constructor which will store its virtual table pointer at the same location and then its attributes after the attributes that would have been stored by the base constructor. It then returns to the most derived constructor, which stores a pointer to its virtual table at the same location and and then stores its attributes after the attributes that would have been stored by the middle constructor.</p>\n<p>Because the virtual table pointer is overwritten, the virtual table pointer ends up always being the one of the most derived class. Virtualness propagates towards the most derived class so if a function is virtual in the middle class, it will be virtual in the most derived class but not the base class. If you polymorphically cast an instance of the most derived class to a pointer to the base class then the compiler will not resolve this to an indirect call to the virtual table and instead will call the function directly <code>A::function()</code>. If a function is virtual for the type you have cast it to then it will resolve to a call into the virtual table which will always be that of the most derived class. If it is not virtual for that type then it will just call <code>Type::function()</code> and pass the object pointer to it, cast to Type.</p>\n<p>Actually when I say pointer to its virtual table, it\'s actually always an offset of 16 into the virtual table.</p>\n<pre><code>vtable for Base:\n        .quad   0\n        .quad   typeinfo for Base\n        .quad   Base::CommonFunction()\n        .quad   Base::VirtualFunction()\n\npointer is typically to the first function i.e. \n\n        mov     edx, OFFSET FLAT:vtable for Base+16\n</code></pre>\n<p><code>virtual</code> is not required again in more-derived classes if it is virtual in a less-derived class because it propagates downwards in the direction of the most derived class. But it can be used to show that the function is indeed a virtual function, without having to check the classes it inherits\'s type definitions. When a function is declared virtual, from that point on, only the last implementation in the inheritance chain is used, but before that, it can still be used non-virtually if the object is cast to a type of a class before that in the inheritance chain that defines that method. It can be defined non-virtually in multiple classes before it in the chain before the virtualhood begins for a method of that name and signature, and they will use their own methods when referenced (and all classes after that definition in the chain will use that definition if they do not have their own definition, as opposed to virtual, which always uses the final definition). When a method is declared virtual, it must be implemented in that class or a more derived class in the inheritance chain for the full object that was constructed in order to be used.</p>\n<p><code>override</code> is another compiler guard that says that this function is overriding something and if it isn\'t then throw a compiler error.</p>\n<p><code>= 0</code> means that this is an abstract function</p>\n<p><code>final</code> prevents a virtual function from being implemented again in a more derived class and will make sure that the virtual table of the most derived class contains the final function of that class.</p>\n<p><code>= default</code> makes it explicit in documentation that the compiler will use the default implementation</p>\n<p><code>= delete</code> give a compiler error if a call to this is attempted</p>\n<p>If you call a non-virtual function, it will resolve to the correct method definition without going through the virtual table. If you call a virtual-function that has its final definition in an inherited class then it will use its virtual table and will pass the subobject to it automatically if you don\'t cast the object pointer to that type when calling the method. If you call a virtual function defined in the most derived class on a pointer of that type then it will use its virtual table, which will be the one at the start of the object. If you call it on a pointer of an inherited type and the function is also virtual in that class then it will use the vtable pointer of that subobject, which in the case of the first subobject will be the same pointer as the most derived class, which will not contain a thunk as the address of the object and the subobject are the same, and therefore it\'s just as simple as the method automatically recasting this pointer, but in the case of a 2nd sub object, its vtable will contain a non-virtual thunk to convert the pointer of the object of inherited type to the type the implementation in the most derived class expects, which is the full object, and therefore offsets the subobject pointer to point to the full object, and in the case of base subobject, will require a virtual thunk to offset the pointer to the base to the full object, such that it can be recast by the method hidden object parameter type.</p>\n<p>Using the object with a reference operator and not through a pointer (dereference operator) breaks polymorphism and will treat virtual methods as regular methods. This is because polymorphic casting on non-pointer types can\'t occur due to slicing.</p>\n<h2>Virtual Inheritance</h2>\n<p>Consider</p>\n<pre><code>class Base\n  {\n      int a = 1;\n      int b = 2;\n  public:\n      void virtual CommonFunction(){} ; //define empty method body\n      void virtual VirtualFunction(){} ;\n  };\n\n\nclass DerivedClass1: virtual public Base\n  {\n      int c = 3;\n  public:\n    void virtual DerivedCommonFunction(){} ;\n     void virtual VirtualFunction(){} ;\n  };\n  \n  class DerivedClass2 : virtual public Base\n {\n     int d = 4;\n public:\n     //void virtual DerivedCommonFunction(){} ;    \n     void virtual VirtualFunction(){} ;\n     void virtual DerivedCommonFunction2(){} ;\n };\n\nclass DerivedDerivedClass :  public DerivedClass1, public DerivedClass2\n {\n   int e = 5;\n public:\n     void virtual DerivedDerivedCommonFunction(){} ;\n     void virtual VirtualFunction(){} ;\n };\n \n int main () {\n   DerivedDerivedClass* d = new DerivedDerivedClass;\n   d-&gt;VirtualFunction();\n   d-&gt;DerivedCommonFunction();\n   d-&gt;DerivedCommonFunction2();\n   d-&gt;DerivedDerivedCommonFunction();\n   ((DerivedClass2*)d)-&gt;DerivedCommonFunction2();\n   ((Base*)d)-&gt;VirtualFunction();\n }\n</code></pre>\n<p>Without virtually inheriting the bass class you will get an object that looks like this:</p>\n<img src="https://i.stack.imgur.com/Z00no.png" width="200">\n<p>Instead of this:</p>\n<img src="https://i.stack.imgur.com/XifNw.png" width="200">\n<p>I.e. there will be 2 base objects.</p>\n<p>In the virtual diamond inheritance situation above, after <code>new</code> is called, it passes the address of the allocated space for the object to the most derived constructor <code>DerivedDerivedClass::DerivedDerivedClass()</code>, which calls <code>Base::Base()</code> first, which writes its vtable in the base\'s dedicated subobject, it then <code>DerivedDerivedClass::DerivedDerivedClass()</code> calls <code>DerivedClass1::DerivedClass1()</code>, which writes its virtual table pointer to its subobject as well as overwriting the base subobject\'s pointer at the end of the object by consulting the passed VTT, and then calls <code>DerivedClass1::DerivedClass1()</code> to do the same, and finally <code>DerivedDerivedClass::DerivedDerivedClass()</code> overwrites all 3 pointers with its virtual table pointer for that inherited class. This is instead of (as illustrated in the 1st image above) <code>DerivedDerivedClass::DerivedDerivedClass()</code> calling <code>DerivedClass1::DerivedClass1()</code> and that calling <code>Base::Base()</code> (which overwrites the virtual pointer), returning, offsetting the address to the next subobject, calling <code>DerivedClass2::DerivedClass2()</code> and then that also calling <code>Base::Base()</code>, overwriting that virtual pointer, returning and then <code>DerivedDerivedClass</code> constructor overwriting both virtual pointers with its virtual table pointer (in this instance, the virtual table of the most derived constructor contains 2 subtables instead of 3).</p>\n<p>The following is all compiled in debug mode -O0 so there will be redundant assembly</p>\n<pre><code>main:\n.LFB8:\n        push    rbp\n        mov     rbp, rsp\n        push    rbx\n        sub     rsp, 24\n        mov     edi, 48 //pass size to new\n        call    operator new(unsigned long) //call new\n        mov     rbx, rax  //move the address of the allocation to rbx\n        mov     rdi, rbx  //move it to rdi i.e. pass to the call\n        call    DerivedDerivedClass::DerivedDerivedClass() [complete object constructor] //construct on this address\n        mov     QWORD PTR [rbp-24], rbx  //store the address of the object on the stack as the d pointer variable on -O0, will be optimised off on -Ofast if the address of the pointer itself isn\'t taken in the code, because this address does not need to be on the stack, it can just be passed in a register to the subsequent methods\n</code></pre>\n<p>Parenthetically, if the code were <code>DerivedDerivedClass d = DerivedDerivedClass()</code>, the <code>main</code> function would look like this:</p>\n<pre><code>main:\n        push    rbp\n        mov     rbp, rsp\n        sub     rsp, 48 // make room for and zero 48 bytes on the stack for the 48 byte object, no extra padding required as the frame is 64 bytes with `rbp` and return address of the function it calls (no stack params are passed to any function it calls), hence rsp will be aligned by 16 assuming it was aligned at the start of this frame\n        mov     QWORD PTR [rbp-48], 0\n        mov     QWORD PTR [rbp-40], 0\n        mov     QWORD PTR [rbp-32], 0\n        mov     QWORD PTR [rbp-24], 0\n        mov     QWORD PTR [rbp-16], 0\n        mov     QWORD PTR [rbp-8], 0\n        lea     rax, [rbp-48] // load the address of the cleared 48 bytes\n        mov     rdi, rax // pass the address as a pointer to the 48 bytes cleared as the first parameter to the constructor\n        call    DerivedDerivedClass::DerivedDerivedClass() [complete object constructor]\n        //address is not stored on the stack because the object is used directly -- there is no pointer variable -- d refers to the object on the stack as opposed to being a pointer\n</code></pre>\n<p>Moving back to the original example, the <code>DerivedDerivedClass</code> constructor:</p>\n<pre><code>DerivedDerivedClass::DerivedDerivedClass() [complete object constructor]:\n.LFB20:\n        push    rbp\n        mov     rbp, rsp\n        sub     rsp, 16\n        mov     QWORD PTR [rbp-8], rdi\n.LBB5:\n        mov     rax, QWORD PTR [rbp-8] // object address now in rax \n        add     rax, 32 //increment address by 32\n        mov     rdi, rax // move object address+32 to rdi i.e. pass to call\n        call    Base::Base() [base object constructor]\n        mov     rax, QWORD PTR [rbp-8] //move object address to rax\n        mov     edx, OFFSET FLAT:VTT for DerivedDerivedClass+8 //move address of VTT+8 to edx\n        mov     rsi, rdx //pass VTT+8 address as 2nd parameter \n        mov     rdi, rax //object address as first (DerivedClass1 subobject)\n        call    DerivedClass1::DerivedClass1() [base object constructor]\n        mov     rax, QWORD PTR [rbp-8] //move object address to rax\n        add     rax, 16  //increment object address by 16\n        mov     edx, OFFSET FLAT:VTT for DerivedDerivedClass+24  //store address of VTT+24 in edx\n        mov     rsi, rdx //pass address of VTT+24 as second parameter\n        mov     rdi, rax //address of DerivedClass2 subobject as first\n        call    DerivedClass2::DerivedClass2() [base object constructor]\n        mov     edx, OFFSET FLAT:vtable for DerivedDerivedClass+24 //move this to edx\n        mov     rax, QWORD PTR [rbp-8] // object address now in rax\n        mov     QWORD PTR [rax], rdx. //store address of vtable for DerivedDerivedClass+24 at the start of the object\n        mov     rax, QWORD PTR [rbp-8] // object address now in rax\n        add     rax, 32  // increment object address by 32\n        mov     edx, OFFSET FLAT:vtable for DerivedDerivedClass+120 //move this to edx\n        mov     QWORD PTR [rax], rdx  //store vtable for DerivedDerivedClass+120 at object+32 (Base) \n        mov     edx, OFFSET FLAT:vtable for DerivedDerivedClass+72 //store this in edx\n        mov     rax, QWORD PTR [rbp-8] //move object address to rax\n        mov     QWORD PTR [rax+16], rdx //store vtable for DerivedDerivedClass+72 at object+16 (DerivedClass2)\n        mov     rax, QWORD PTR [rbp-8]\n        mov     DWORD PTR [rax+28], 5 // stores e = 5 in the object\n.LBE5:\n        nop\n        leave\n        ret\n</code></pre>\n<p>The <code>DerivedDerivedClass</code> constructor calls <code>Base::Base()</code> with a pointer to the object offset 32. Base stores a pointer to its virtual table at the address it receives and its members after it.</p>\n<pre><code>Base::Base() [base object constructor]:\n.LFB11:\n        push    rbp\n        mov     rbp, rsp\n        mov     QWORD PTR [rbp-8], rdi //stores address of object on stack (-O0)\n.LBB2:\n        mov     edx, OFFSET FLAT:vtable for Base+16  //puts vtable for Base+16 in edx\n        mov     rax, QWORD PTR [rbp-8] //copies address of object from stack to rax\n        mov     QWORD PTR [rax], rdx  //stores it address of object\n        mov     rax, QWORD PTR [rbp-8] //copies address of object on stack to rax again\n        mov     DWORD PTR [rax+8], 1 //stores a = 1 in the object\n        mov     rax, QWORD PTR [rbp-8] //junk from -O0\n        mov     DWORD PTR [rax+12], 2  //stores b = 2 in the object\n.LBE2:\n        nop\n        pop     rbp\n        ret\n</code></pre>\n<p><code>DerivedDerivedClass::DerivedDerivedClass()</code> then calls <code>DerivedClass1::DerivedClass1()</code> with a pointer to the object offset 0 and also passes the address of <code>VTT for DerivedDerivedClass+8</code></p>\n<pre><code>DerivedClass1::DerivedClass1() [base object constructor]:\n.LFB14:\n        push    rbp\n        mov     rbp, rsp\n        mov     QWORD PTR [rbp-8], rdi //address of object\n        mov     QWORD PTR [rbp-16], rsi  //address of VTT+8\n.LBB3:\n        mov     rax, QWORD PTR [rbp-16]  //address of VTT+8 now in rax\n        mov     rdx, QWORD PTR [rax]     //address of DerivedClass1-in-DerivedDerivedClass+24 now in rdx\n        mov     rax, QWORD PTR [rbp-8]   //address of object now in rax\n        mov     QWORD PTR [rax], rdx     //store address of DerivedClass1-in-.. in the object\n        mov     rax, QWORD PTR [rbp-8]  // address of object now in rax\n        mov     rax, QWORD PTR [rax]    //address of DerivedClass1-in.. now implicitly in rax\n        sub     rax, 24                 //address of DerivedClass1-in-DerivedDerivedClass+0 now in rax\n        mov     rax, QWORD PTR [rax]    //value of 32 now in rax\n        mov     rdx, rax                // now in rdx\n        mov     rax, QWORD PTR [rbp-8]  //address of object now in rax\n        add     rdx, rax                //address of object+32 now in rdx\n        mov     rax, QWORD PTR [rbp-16]  //address of VTT+8 now in rax\n        mov     rax, QWORD PTR [rax+8]   //derference VTT+8+8; address of DerivedClass1-in-DerivedDerivedClass+72 (Base::CommonFunction()) now in rax\n        mov     QWORD PTR [rdx], rax     //store at address object+32 (offset to Base)\n        mov     rax, QWORD PTR [rbp-8]  //store address of object in rax, return\n        mov     DWORD PTR [rax+8], 3    //store its attribute c = 3 in the object\n.LBE3:\n        nop\n        pop     rbp\n        ret\n</code></pre>\n<pre><code>VTT for DerivedDerivedClass:\n        .quad   vtable for DerivedDerivedClass+24\n        .quad   construction vtable for DerivedClass1-in-DerivedDerivedClass+24 //(DerivedClass1 uses this to write its vtable pointer)\n        .quad   construction vtable for DerivedClass1-in-DerivedDerivedClass+72 //(DerivedClass1 uses this to overwrite the base vtable pointer)\n        .quad   construction vtable for DerivedClass2-in-DerivedDerivedClass+24\n        .quad   construction vtable for DerivedClass2-in-DerivedDerivedClass+72\n        .quad   vtable for DerivedDerivedClass+120 // DerivedDerivedClass supposed to use this to overwrite Bases\'s vtable pointer\n        .quad   vtable for DerivedDerivedClass+72 // DerivedDerivedClass supposed to use this to overwrite DerivedClass2\'s vtable pointer\n//although DerivedDerivedClass uses vtable for DerivedDerivedClass+72 and DerivedDerivedClass+120 directly to overwrite them instead of going through the VTT\n\nconstruction vtable for DerivedClass1-in-DerivedDerivedClass:\n        .quad   32\n        .quad   0\n        .quad   typeinfo for DerivedClass1\n        .quad   DerivedClass1::DerivedCommonFunction()\n        .quad   DerivedClass1::VirtualFunction()\n        .quad   -32\n        .quad   0\n        .quad   -32\n        .quad   typeinfo for DerivedClass1\n        .quad   Base::CommonFunction()\n        .quad   virtual thunk to DerivedClass1::VirtualFunction()\nconstruction vtable for DerivedClass2-in-DerivedDerivedClass:\n        .quad   16\n        .quad   0\n        .quad   typeinfo for DerivedClass2\n        .quad   DerivedClass2::VirtualFunction()\n        .quad   DerivedClass2::DerivedCommonFunction2()\n        .quad   -16\n        .quad   0\n        .quad   -16\n        .quad   typeinfo for DerivedClass2\n        .quad   Base::CommonFunction()\n        .quad   virtual thunk to DerivedClass2::VirtualFunction()\nvtable for DerivedDerivedClass:\n        .quad   32\n        .quad   0\n        .quad   typeinfo for DerivedDerivedClass\n        .quad   DerivedClass1::DerivedCommonFunction()\n        .quad   DerivedDerivedClass::VirtualFunction()\n        .quad   DerivedDerivedClass::DerivedDerivedCommonFunction()\n        .quad   16\n        .quad   -16\n        .quad   typeinfo for DerivedDerivedClass\n        .quad   non-virtual thunk to DerivedDerivedClass::VirtualFunction()\n        .quad   DerivedClass2::DerivedCommonFunction2()\n        .quad   -32\n        .quad   0\n        .quad   -32\n        .quad   typeinfo for DerivedDerivedClass\n        .quad   Base::CommonFunction()\n        .quad   virtual thunk to DerivedDerivedClass::VirtualFunction()\n\nvirtual thunk to DerivedClass1::VirtualFunction():\n        mov     r10, QWORD PTR [rdi]\n        add     rdi, QWORD PTR [r10-32]\n        jmp     .LTHUNK0\nvirtual thunk to DerivedClass2::VirtualFunction():\n        mov     r10, QWORD PTR [rdi]\n        add     rdi, QWORD PTR [r10-32]\n        jmp     .LTHUNK1\nvirtual thunk to DerivedDerivedClass::VirtualFunction():\n        mov     r10, QWORD PTR [rdi]\n        add     rdi, QWORD PTR [r10-32]\n        jmp     .LTHUNK2\nnon-virtual thunk to DerivedDerivedClass::VirtualFunction():\n        sub     rdi, 16\n        jmp     .LTHUNK3\n\n        .set    .LTHUNK0,DerivedClass1::VirtualFunction()\n        .set    .LTHUNK1,DerivedClass2::VirtualFunction()\n        .set    .LTHUNK2,DerivedDerivedClass::VirtualFunction()\n        .set    .LTHUNK3,DerivedDerivedClass::VirtualFunction()\n\n\n</code></pre>\n<p>Each inherited class has its own construction virtual table and the most derived class, <code>DerivedDerivedClass</code>, has a virtual table with a subtable for each, and it uses the pointer to the subtable to overwrite construction vtable pointer that the inherited class\'s constructor stored for each subobject. Each virtual method that needs a thunk (virtual thunk offsets the object pointer from the base to the start of the object and a non-virtual thunk offsets the object pointer from an inherited class\'s object that isn\'t the base object to the start of the whole object of the type <code>DerivedDerivedClass</code>). The <code>DerivedDerivedClass</code> constructor also uses a virtual table table (VTT) as a serial list of all the virtual table pointers that it needs to use and passes it to each constructor (along with the subobject address that the constructor is for), which they use to overwrite their and the base\'s vtable pointer.</p>\n<p><code>DerivedDerivedClass::DerivedDerivedClass()</code> then passes the address of the object+16 and the address of VTT for <code>DerivedDerivedClass+24</code> to <code>DerivedClass2::DerivedClass2()</code> whose assembly is identical to <code>DerivedClass1::DerivedClass1()</code> except for the line <code>mov     DWORD PTR [rax+8], 3</code> which obviously has a 4 instead of 3 for <code>d = 4</code>.</p>\n<p>After this, it replaces all 3 virtual table pointers in the object with pointers to offsets in <code>DerivedDerivedClass</code>\'s vtable to the representation for that class.</p>\n<p>The call to <code>d-&gt;VirtualFunction()</code> in <code>main</code>:</p>\n<pre><code>        mov     rax, QWORD PTR [rbp-24] //store pointer to object (and hence vtable pointer) in rax\n        mov     rax, QWORD PTR [rax] //dereference this pointer to vtable pointer and store virtual table pointer in rax\n        add     rax, 8 // add 8 to the pointer to get the 2nd function pointer in the table\n        mov     rdx, QWORD PTR [rax] //dereference this pointer to get the address of the method to call\n        mov     rax, QWORD PTR [rbp-24] //restore pointer to object in rax (-O0 is inefficient, yes)\n        mov     rdi, rax  //pass object to the method\n        call    rdx\n</code></pre>\n<p><code>d-&gt;DerivedCommonFunction();</code>:</p>\n<pre><code>        mov     rax, QWORD PTR [rbp-24]\n        mov     rdx, QWORD PTR [rbp-24]\n        mov     rdx, QWORD PTR [rdx]\n        mov     rdx, QWORD PTR [rdx]\n        mov     rdi, rax  //pass object to method\n        call    rdx  //call the first function in the table\n</code></pre>\n<p><code>d-&gt;DerivedCommonFunction2();</code>:</p>\n<pre><code>        mov     rax, QWORD PTR [rbp-24] //get the object pointer\n        lea     rdx, [rax+16]  //get the address of the 2nd subobject in the object\n        mov     rax, QWORD PTR [rbp-24] //get the object pointer\n        mov     rax, QWORD PTR [rax+16] // get the vtable pointer of the 2nd subobject\n        add     rax, 8  //call the 2nd function in this table\n        mov     rax, QWORD PTR [rax]  //get the address of the 2nd function\n        mov     rdi, rdx  //call it and pass the 2nd subobject to it\n        call    rax\n</code></pre>\n<p><code>d-&gt;DerivedDerivedCommonFunction();</code>:</p>\n<pre><code>        mov     rax, QWORD PTR [rbp-24] //get the object pointer\n        mov     rax, QWORD PTR [rax] //get the vtable pointer\n        add     rax, 16 //get the 3rd function in the first virtual table (which is where virtual functions that that first appear in the most derived class go, because they belong to the full object which uses the virtual table pointer at the start of the object)\n        mov     rdx, QWORD PTR [rax] //get the address of the object\n        mov     rax, QWORD PTR [rbp-24]\n        mov     rdi, rax  //call it and pass the whole object to it\n        call    rdx\n</code></pre>\n<p><code>((DerivedClass2*)d)-&gt;DerivedCommonFunction2();</code>:</p>\n<pre><code>//it casts the object to its subobject and calls the corresponding method in its virtual table, which will be a non-virtual thunk\n\n        cmp     QWORD PTR [rbp-24], 0\n        je      .L14\n        mov     rax, QWORD PTR [rbp-24]\n        add     rax, 16\n        jmp     .L15\n.L14:\n        mov     eax, 0\n.L15:\n        cmp     QWORD PTR [rbp-24], 0\n        cmp     QWORD PTR [rbp-24], 0\n        je      .L18\n        mov     rdx, QWORD PTR [rbp-24]\n        add     rdx, 16\n        jmp     .L19\n.L18:\n        mov     edx, 0\n.L19:\n        mov     rdx, QWORD PTR [rdx]\n        add     rdx, 8\n        mov     rdx, QWORD PTR [rdx]\n        mov     rdi, rax\n        call    rdx\n</code></pre>\n<p><code>((Base*)d)-&gt;VirtualFunction();</code>:</p>\n<pre><code>//it casts the object to its subobject and calls the corresponding function in its virtual table, which will be a virtual thunk\n\n        cmp     QWORD PTR [rbp-24], 0\n        je      .L20\n        mov     rax, QWORD PTR [rbp-24]\n        mov     rax, QWORD PTR [rax]\n        sub     rax, 24\n        mov     rax, QWORD PTR [rax]\n        mov     rdx, rax\n        mov     rax, QWORD PTR [rbp-24]\n        add     rax, rdx\n        jmp     .L21\n.L20:\n        mov     eax, 0\n.L21:\n        cmp     QWORD PTR [rbp-24], 0\n        cmp     QWORD PTR [rbp-24], 0\n        je      .L24\n        mov     rdx, QWORD PTR [rbp-24]\n        mov     rdx, QWORD PTR [rdx]\n        sub     rdx, 24\n        mov     rdx, QWORD PTR [rdx]\n        mov     rcx, rdx\n        mov     rdx, QWORD PTR [rbp-24]\n        add     rdx, rcx\n        jmp     .L25\n.L24:\n        mov     edx, 0\n.L25:\n        mov     rdx, QWORD PTR [rdx]\n        add     rdx, 8\n        mov     rdx, QWORD PTR [rdx]\n        mov     rdi, rax\n        call    rdx\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/21558', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1556/']