{"id":4343,"date":"2021-11-16T16:57:21","date_gmt":"2021-11-16T14:57:21","guid":{"rendered":"https:\/\/mariusbancila.ro\/blog\/?p=4343"},"modified":"2021-11-16T22:05:57","modified_gmt":"2021-11-16T20:05:57","slug":"virtual-inheritance-in-c","status":"publish","type":"post","link":"https:\/\/mariusbancila.ro\/blog\/2021\/11\/16\/virtual-inheritance-in-c\/","title":{"rendered":"Virtual Inheritance in C++"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">The C++ language supports the concept of multiple inheritance. This means one class can have multiple base classes. This feature is not available in other languages, such as C# or Java. The designers of these languages didn&#8217;t considered the benefits of supporting this feature to worth the effort. And probably one of the reasons is that multiple inheritance may lead to the so-called diamond inheritance problem, when one class derives from two different classes, that in turn derive from the same class. In this article, I will discuss the problem as well as the solution in C++.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">The problem<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To understand the problem, let&#8217;s start with the following class hierarchy:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/cd1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"381\" height=\"499\" src=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/cd1.png\" alt=\"\" class=\"wp-image-4344\" srcset=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/cd1.png 381w, https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/cd1-229x300.png 229w\" sizes=\"auto, (max-width: 381px) 100vw, 381px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This is a simple hierarchy with the following classes:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>control<\/code> is the base class of all visual elements and has some data members such as <code>id<\/code>, <code>width<\/code>, and <code>height<\/code><\/li><li><code>image<\/code> and <code>button<\/code> are classes derived from control, each with its own additional data members<\/li><li><code>image_button<\/code> that is both an image and a button and inherits from these two classes, also with its own additional data members<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This can be represented in code as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">struct control\n{\n   int id;\n   int width;\n   int height;\n};\n\nstruct image : public control\n{\n   int stretch_style;\n   int stretch_direction;\n};\n\nstruct button : public control\n{\n   int text_alignment;\n};\n\nstruct image_button : public image, public button\n{\n   int content_alignment;\n};<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The image above shows the inheritance hierarchy, but the object memory layout is different. This actually looks like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"447\" height=\"573\" src=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout1.png\" alt=\"\" class=\"wp-image-4350\" srcset=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout1.png 447w, https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout1-234x300.png 234w\" sizes=\"auto, (max-width: 447px) 100vw, 447px\" \/><\/a><figcaption><em>Object memory layout<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">What we can see from here is that:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>image<\/code> contains everything that <code>control<\/code> has plus its own data members<\/li><li><code>button<\/code> contains everything that <code>control<\/code> has plus its own data members<\/li><li><code>image_button<\/code> contains everything that <code>image<\/code> and <code>button<\/code> has plus its own data members; however, this implies it has two copies of the data members of <code>control<\/code>.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">As a result, trying to access any of the data members from <code>control<\/code> using an <code>image_button<\/code> object results in a compiler error.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">image i;\ni.id = 1;     \/\/ OK\n\nbutton b;\nb.id = 2;     \/\/ OK\n\nimage_button ib;\nib.id = 3;    \/\/ error<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">error C2385: ambiguous access of 'id'\nmessage : could be the 'id' in base 'control'\nmessage : could be the 'id' in base 'control'<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In this example, we only had data members but the same problem occurs with member functions.<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/cd2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"376\" height=\"504\" src=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/cd2.png\" alt=\"\" class=\"wp-image-4353\" srcset=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/cd2.png 376w, https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/cd2-224x300.png 224w\" sizes=\"auto, (max-width: 376px) 100vw, 376px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:18px\">A slightly modified version of the class hierarchy with a virtual function <code>draw()<\/code> overridden in each class, and a member function <code>resize()<\/code> in the <code>control<\/code> base class.<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"444\" height=\"672\" src=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout2.png\" alt=\"\" class=\"wp-image-4354\" srcset=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout2.png 444w, https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout2-198x300.png 198w\" sizes=\"auto, (max-width: 444px) 100vw, 444px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\" style=\"font-size:18px\">Memory layout now contains additional a pointer to a virtual table.<\/p>\n<\/div>\n<\/div>\n<\/div><\/div>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">struct control\n{\n   int id;\n   int width;\n   int height;\n\n   void resize(int const w, int const h, bool const redraw = true) \n   {\n      width = w;\n      height = h;\n      if(redraw)\n         draw();\n   }\n\n   virtual void draw() \n   { \n      std::cout &lt;&lt; \"control::draw\\n\"; \n   }\n};\n\nstruct image : public control\n{\n   int stretch_style;\n   int stretch_direction;\n\n   virtual void draw() override\n   { \n      control::draw(); \n      std::cout &lt;&lt; \"image::draw\\n\"; \n   }\n};\n\nstruct button : public control\n{\n   int text_alignment;\n\n   virtual void draw() override\n   { \n      control::draw(); \n      std::cout &lt;&lt; \"button::draw\\n\"; \n   }\n};\n\nstruct image_button : public image, public button\n{\n   int content_alignment;\n\n   virtual void draw() override\n   {\n      button::draw();\n      image::draw();\n      std::cout &lt;&lt; \"image_button::draw\\n\";\n   }\n};\n\nint main()\n{\n   image i;\n   i.id = 1;           \/\/ OK\n   i.resize(32, 32);   \/\/ OK\n\n   button b;\n   b.id = 2;           \/\/ OK\n   b.resize(100, 20);  \/\/ OK\n\n   image_button ib;\n   ib.id = 3;          \/\/ error\n   ib.resize(100, 20); \/\/ error\n}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">The solution<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Here is where virtual inheritance comes to rescue. By declaring a base class as <code>virtual<\/code> you are ensuring that the memory layout does not duplicate the base class members.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">struct control\n{\n   int id;\n   int width;\n   int height;\n};\n\nstruct image : virtual public control\n{\n   int stretch_style;\n   int stretch_direction;\n};\n\nstruct button : virtual public control\n{\n   int text_alignment;\n};\n\nstruct image_button : public image, public button\n{\n   int content_alignment;\n};<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Note<\/strong>: the <code>virtual<\/code> keyword can be use either before or after the access specifier. Therefore <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">virtual public control<\/code> and <code data-enlighter-language=\"generic\" class=\"EnlighterJSRAW\">public virtual control<\/code> are equivalent.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The memory layout of the image_button class looks as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout3.png\"><img loading=\"lazy\" decoding=\"async\" width=\"432\" height=\"459\" src=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout3.png\" alt=\"\" class=\"wp-image-4358\" srcset=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout3.png 432w, https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout3-282x300.png 282w\" sizes=\"auto, (max-width: 432px) 100vw, 432px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">From this representation, we can see that:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>there is no duplication of the data members from the <code>control<\/code> base class<\/li><li>the data members from the <code>control<\/code> class are present at the end of the layout<\/li><li>there is a pointer to a virtual base table for both the <code>image<\/code> and <code>button<\/code> classes<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">With virtual functions added to these classes, the memory layout will also contain a pointer to the virtual function table in the <code>control<\/code> base class.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">struct control\n{\n   int id;\n   int width;\n   int height;\n\n   void resize(int const w, int const h, bool const redraw = true) \n   {\n      width = w;\n      height = h;\n      if(redraw)\n         draw();\n   }\n\n   virtual void draw() \n   { \n      std::cout &lt;&lt; \"control::draw\\n\"; \n   }\n};\n\nstruct image : virtual public control\n{\n   int stretch_style;\n   int stretch_direction;\n\n   virtual void draw() override\n   { \n      control::draw(); \n      std::cout &lt;&lt; \"image::draw\\n\"; \n   }\n};\n\nstruct button : virtual public control\n{\n   int text_alignment;\n\n   virtual void draw() override\n   { \n      control::draw(); \n      std::cout &lt;&lt; \"button::draw\\n\"; \n   }\n};\n\nstruct image_button : public image, public button\n{\n   int content_alignment;\n\n   virtual void draw() override\n   {\n      button::draw();\n      image::draw();\n      std::cout &lt;&lt; \"image_button::draw\\n\";\n   }\n};<\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout4-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"433\" height=\"552\" src=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout4-1.png\" alt=\"\" class=\"wp-image-4362\" srcset=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout4-1.png 433w, https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout4-1-235x300.png 235w\" sizes=\"auto, (max-width: 433px) 100vw, 433px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">However, now we can write the following snippet without getting any more errors:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int main()\n{\n   image i;\n   i.id = 1;           \/\/ OK\n   i.resize(32, 32);   \/\/ OK\n\n   button b;\n   b.id = 2;           \/\/ OK\n   b.resize(100, 20);  \/\/ OK\n\n   image_button ib;\n   ib.id = 3;          \/\/ OK\n   ib.resize(100, 20); \/\/ OK\n}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Construction and destruction of objects<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">When we have a virtual hierarchy, constructors and destructors are invoked as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>virtual base classes are constructed before non-virtual base classes; therefore, their constructors are called first in the order they appear in a depth-first, left-to-right traversal of the graph of base classes<\/li><li>constructors for the rest of the classes are then called, from base class to derived class<\/li><li>destructors are called in the opposite order of construction<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s look at the following example:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">struct control\n{\n   int id;\n   int width;\n   int height;\n\n   control(int const i) :id(i)\n   {\n      std::cout &lt;&lt; \"control ctor\\n\";\n   }\n\n   virtual ~control()\n   {\n      std::cout &lt;&lt; \"control dtor\\n\";\n   }\n\n   void resize(int const w, int const h, bool const redraw = true) \n   {\n      width = w;\n      height = h;\n      if(redraw)\n         draw();\n   }\n\n   virtual void draw() \n   { \n      std::cout &lt;&lt; \"control::draw\\n\"; \n   }\n};\n\nstruct image : virtual public control\n{\n   int stretch_style;\n   int stretch_direction;\n\n   image(int const i) :control(i)\n   {\n      std::cout &lt;&lt; \"image ctor\\n\";\n   }\n\n   virtual ~image()\n   {\n      std::cout &lt;&lt; \"image dtor\\n\";\n   }\n\n   virtual void draw() override\n   { \n      control::draw(); \n      std::cout &lt;&lt; \"image::draw\\n\"; \n   }\n};\n\nstruct button : virtual public control\n{\n   int text_alignment;\n\n   button(int const i) :control(i)\n   {\n      std::cout &lt;&lt; \"button ctor\\n\";\n   }\n\n   virtual ~button()\n   {\n      std::cout &lt;&lt; \"button dtor\\n\";\n   }\n\n   virtual void draw() override\n   { \n      control::draw(); \n      std::cout &lt;&lt; \"button::draw\\n\"; \n   }\n};\n\nstruct image_button : public image, public button\n{\n   int content_alignment;\n\n   image_button(int const i) : image(i), button(i), control(i)\n   {\n      std::cout &lt;&lt; \"image_button ctor\\n\";\n   }\n\n   ~image_button()\n   {\n      std::cout &lt;&lt; \"image_button dtor\\n\";\n   }\n\n   virtual void draw() override\n   {\n      button::draw();\n      image::draw();\n      std::cout &lt;&lt; \"image_button::draw\\n\";\n   }\n};\n\nint main()\n{\n   image_button ib{ 3 };\n   ib.resize(100, 20);\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The output of this program is as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">control ctor\nimage ctor\nbutton ctor\nimage_button ctor\ncontrol::draw\nbutton::draw\ncontrol::draw\nimage::draw\nimage_button::draw\nimage_button dtor\nbutton dtor\nimage dtor\ncontrol dtor<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A class may have both virtual and non-virtual base classes. We can change the previous example in order to demonstrate what happens in this case. Let&#8217;s consider the following modified class hierarchy:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/cd3-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"573\" height=\"509\" src=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/cd3-1.png\" alt=\"\" class=\"wp-image-4364\" srcset=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/cd3-1.png 573w, https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/cd3-1-300x266.png 300w\" sizes=\"auto, (max-width: 573px) 100vw, 573px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The new hierarchy differs from the previous on as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>the <code>image<\/code> class has two base classes: non-virtual base <code>flippable<\/code> and virtual base <code>control<\/code><\/li><li>the <code>button<\/code> class has two base classes also, both virtual: <code>control<\/code> and <code>clickable<\/code><\/li><li>the <code>image_button<\/code> class has three base classes: non-virtual bases <code>image<\/code> and <code>button<\/code>, and virtual base class <code>clickable<\/code><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The modified implementation of these classes is shown below:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">struct control\n{\n   int id;\n   int width;\n   int height;\n\n   control(int const i) :id(i)\n   {\n      std::cout &lt;&lt; \"control ctor\\n\";\n   }\n\n   virtual ~control()\n   {\n      std::cout &lt;&lt; \"control dtor\\n\";\n   }\n\n   void resize(int const w, int const h, bool const redraw = true) \n   {\n      width = w;\n      height = h;\n      if(redraw)\n         draw();\n   }\n\n   virtual void draw() \n   { \n      std::cout &lt;&lt; \"control::draw\\n\"; \n   }\n};\n\nstruct flippable\n{\n   int axis;\n\n   flippable()\n   {\n      std::cout &lt;&lt; \"flippable ctor\\n\";\n   }\n\n   virtual ~flippable()\n   {\n      std::cout &lt;&lt; \"flippable dtor\\n\";\n   }\n};\n\nstruct image : public flippable, virtual public control\n{\n   int stretch_style;\n   int stretch_direction;\n\n   image(int const i) :control(i)\n   {\n      std::cout &lt;&lt; \"image ctor\\n\";\n   }\n\n   virtual ~image()\n   {\n      std::cout &lt;&lt; \"image dtor\\n\";\n   }\n\n   virtual void draw() override\n   { \n      control::draw(); \n      std::cout &lt;&lt; \"image::draw\\n\"; \n   }\n};\n\nstruct clickable\n{\n   using fn_clicked = void(*)();\n\n   fn_clicked callback = nullptr;\n\n   clickable()\n   {\n      std::cout &lt;&lt; \"clickable ctor\\n\";\n   }\n\n   virtual ~clickable()\n   {\n      std::cout &lt;&lt; \"clickable dtor\\n\";\n   }   \n};\n\nstruct button : virtual public clickable, virtual public control\n{\n   int text_alignment;\n\n   button(int const i) :control(i)\n   {\n      std::cout &lt;&lt; \"button ctor\\n\";\n   }\n\n   virtual ~button()\n   {\n      std::cout &lt;&lt; \"button dtor\\n\";\n   }\n\n   virtual void draw() override\n   { \n      control::draw(); \n      std::cout &lt;&lt; \"button::draw\\n\"; \n   }\n};\n\nstruct image_button : public image, public button, virtual public clickable\n{\n   int content_alignment;\n\n   image_button(int const i) : image(i), button(i), control(i)\n   {\n      std::cout &lt;&lt; \"image_button ctor\\n\";\n   }\n\n   ~image_button()\n   {\n      std::cout &lt;&lt; \"image_button dtor\\n\";\n   }\n\n   virtual void draw() override\n   {\n      button::draw();\n      image::draw();\n      std::cout &lt;&lt; \"image_button::draw\\n\";\n   }\n};<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The new memory layout of the <code>image_button<\/code> class is shown in the following image:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout6.png\"><img loading=\"lazy\" decoding=\"async\" width=\"540\" height=\"818\" src=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout6.png\" alt=\"\" class=\"wp-image-4365\" srcset=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout6.png 540w, https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/layout6-198x300.png 198w\" sizes=\"auto, (max-width: 540px) 100vw, 540px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Again, we can notice several things here:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>the layout of the <code>image<\/code> object contains the <code>flippable<\/code> object, as this class is a non-virtual base<\/li><li>there is only one copy of the <code>clickable<\/code> object layout, as this class is a virtual base class for both <code>button<\/code> and <code>image_button<\/code><\/li><li>the memory layout of the two virtual base classes, <code>control<\/code> and <code>clickable<\/code>, is located at the end of the <code>image_button<\/code> layout<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The new output of the program is listed here:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">control ctor\nclickable ctor\nflippable ctor\nimage ctor\nbutton ctor\nimage_button ctor\ncontrol::draw\nbutton::draw\ncontrol::draw\nimage::draw\nimage_button::draw\nimage_button dtor\nbutton dtor\nimage dtor\nflippable dtor\nclickable dtor\ncontrol dtor<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The order of the constructor calls, as seen here, as well as the destructor calls is following the several rules listed at the beginning of this section.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Alternatives<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Because of this diamond problem, and perhaps because other languages do not support multiple inheritance, there is a considerable opposition to using multiple inheritance. That doesn&#8217;t necessary mean that multiple inheritance is evil or it can&#8217;t be used successfully in various scenarios. Inheritance in general should be used when it has benefits not for the purpose of reusing code. There are many cases when aggregation is a better solution than inheritance.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you do use multiple inheritance, in general, it&#8217;s preferred that the virtual base classes are pure abstract base classes. That means only pure virtual methods and, if possible, no data members either. That is basically the equivalent of interfaces in C# or Java. Using this approach, multiple inheritance becomes equivalent to the single inheritance in these other programming languages.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An alternative to multiple inheritance is using some design patterns. A good example is the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Bridge_pattern\" target=\"_blank\" rel=\"noreferrer noopener\">bridge design pattern<\/a> that allows you to separate abstractions from the implementations.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">References<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You can read more about virtual inheritance here: <a href=\"https:\/\/isocpp.org\/wiki\/faq\/multiple-inheritance\" target=\"_blank\" rel=\"noreferrer noopener\">ISO C++: Inheritance &#8211; multiple and virtual inheritance<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The memory layout images in this article were created using <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=RamonViladomat.StructLayout\" target=\"_blank\" rel=\"noreferrer noopener\">Struct Layout<\/a> &#8211; an extension for Visual Studio.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The class diagram images in this article were created using <a href=\"https:\/\/online.visual-paradigm.com\/diagrams\/solutions\/free-class-diagram-tool\/\" target=\"_blank\" rel=\"noreferrer noopener\">Visual Paradigm Online<\/a> &#8211; a free tool for drawing class diagrams and other UML diagrams.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The C++ language supports the concept of multiple inheritance. This means one class can have multiple base classes. This feature is not available in other languages, such as C# or Java. The designers of these languages didn&#8217;t considered the benefits of supporting this feature to worth the effort. And probably one of the reasons is &#8230; <a title=\"Virtual Inheritance in C++\" class=\"read-more\" href=\"https:\/\/mariusbancila.ro\/blog\/2021\/11\/16\/virtual-inheritance-in-c\/\" aria-label=\"Read more about Virtual Inheritance in C++\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","advgb_blocks_editor_width":"","advgb_blocks_columns_visual_guide":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[7],"tags":[451,639,640],"class_list":["post-4343","post","type-post","status-publish","format-standard","hentry","category-c","tag-c","tag-inheritance","tag-virtual"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"Learn about multiple inheritance in C++, the diamond inheritance problem, and the solution to fix it with virtual inheritance.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Marius Bancila\"\/>\n\t<meta name=\"keywords\" content=\"c++,inheritance,virtual\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/mariusbancila.ro\/blog\/2021\/11\/16\/virtual-inheritance-in-c\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Marius Bancila&#039;s Blog | About code. Mostly on C++\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Virtual inheritance in C++\" \/>\n\t\t<meta property=\"og:description\" content=\"Learn about multiple inheritance in C++, the diamond inheritance problem, and the solution to fix it with virtual inheritance.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/mariusbancila.ro\/blog\/2021\/11\/16\/virtual-inheritance-in-c\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2021-11-16T14:57:21+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2021-11-16T20:05:57+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Virtual inheritance in C++\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Learn about multiple inheritance in C++, the diamond inheritance problem, and the solution to fix it with virtual inheritance.\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/11\\\/16\\\/virtual-inheritance-in-c\\\/#article\",\"name\":\"Virtual inheritance in C++\",\"headline\":\"Virtual Inheritance in C++\",\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/11\\\/cd1.png\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/11\\\/16\\\/virtual-inheritance-in-c\\\/#articleImage\",\"width\":381,\"height\":499,\"caption\":\"Diamond inheritance\"},\"datePublished\":\"2021-11-16T16:57:21+02:00\",\"dateModified\":\"2021-11-16T22:05:57+02:00\",\"inLanguage\":\"en-US\",\"commentCount\":9,\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/11\\\/16\\\/virtual-inheritance-in-c\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/11\\\/16\\\/virtual-inheritance-in-c\\\/#webpage\"},\"articleSection\":\"C++, C++, inheritance, virtual\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/11\\\/16\\\/virtual-inheritance-in-c\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"position\":2,\"name\":\"IT\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"position\":3,\"name\":\"Software\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"position\":4,\"name\":\"C++\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/11\\\/16\\\/virtual-inheritance-in-c\\\/#listItem\",\"name\":\"Virtual Inheritance in C++\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/11\\\/16\\\/virtual-inheritance-in-c\\\/#listItem\",\"position\":5,\"name\":\"Virtual Inheritance in C++\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/\",\"name\":\"Marius Bancila\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/11\\\/16\\\/virtual-inheritance-in-c\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Marius Bancila\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/11\\\/16\\\/virtual-inheritance-in-c\\\/#webpage\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/11\\\/16\\\/virtual-inheritance-in-c\\\/\",\"name\":\"Virtual inheritance in C++\",\"description\":\"Learn about multiple inheritance in C++, the diamond inheritance problem, and the solution to fix it with virtual inheritance.\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2021\\\/11\\\/16\\\/virtual-inheritance-in-c\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"datePublished\":\"2021-11-16T16:57:21+02:00\",\"dateModified\":\"2021-11-16T22:05:57+02:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Virtual inheritance in C++","description":"Learn about multiple inheritance in C++, the diamond inheritance problem, and the solution to fix it with virtual inheritance.","canonical_url":"https:\/\/mariusbancila.ro\/blog\/2021\/11\/16\/virtual-inheritance-in-c\/","robots":"max-image-preview:large","keywords":"c++,inheritance,virtual","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/mariusbancila.ro\/blog\/2021\/11\/16\/virtual-inheritance-in-c\/#article","name":"Virtual inheritance in C++","headline":"Virtual Inheritance in C++","author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2021\/11\/cd1.png","@id":"https:\/\/mariusbancila.ro\/blog\/2021\/11\/16\/virtual-inheritance-in-c\/#articleImage","width":381,"height":499,"caption":"Diamond inheritance"},"datePublished":"2021-11-16T16:57:21+02:00","dateModified":"2021-11-16T22:05:57+02:00","inLanguage":"en-US","commentCount":9,"mainEntityOfPage":{"@id":"https:\/\/mariusbancila.ro\/blog\/2021\/11\/16\/virtual-inheritance-in-c\/#webpage"},"isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/2021\/11\/16\/virtual-inheritance-in-c\/#webpage"},"articleSection":"C++, C++, inheritance, virtual"},{"@type":"BreadcrumbList","@id":"https:\/\/mariusbancila.ro\/blog\/2021\/11\/16\/virtual-inheritance-in-c\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog#listItem","position":1,"name":"Home","item":"https:\/\/mariusbancila.ro\/blog","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","position":2,"name":"IT","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","position":3,"name":"Software","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","position":4,"name":"C++","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2021\/11\/16\/virtual-inheritance-in-c\/#listItem","name":"Virtual Inheritance in C++"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2021\/11\/16\/virtual-inheritance-in-c\/#listItem","position":5,"name":"Virtual Inheritance in C++","previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"}}]},{"@type":"Organization","@id":"https:\/\/mariusbancila.ro\/blog\/#organization","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","url":"https:\/\/mariusbancila.ro\/blog\/"},{"@type":"Person","@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author","url":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/","name":"Marius Bancila","image":{"@type":"ImageObject","@id":"https:\/\/mariusbancila.ro\/blog\/2021\/11\/16\/virtual-inheritance-in-c\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g","width":96,"height":96,"caption":"Marius Bancila"}},{"@type":"WebPage","@id":"https:\/\/mariusbancila.ro\/blog\/2021\/11\/16\/virtual-inheritance-in-c\/#webpage","url":"https:\/\/mariusbancila.ro\/blog\/2021\/11\/16\/virtual-inheritance-in-c\/","name":"Virtual inheritance in C++","description":"Learn about multiple inheritance in C++, the diamond inheritance problem, and the solution to fix it with virtual inheritance.","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/mariusbancila.ro\/blog\/2021\/11\/16\/virtual-inheritance-in-c\/#breadcrumblist"},"author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"creator":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"datePublished":"2021-11-16T16:57:21+02:00","dateModified":"2021-11-16T22:05:57+02:00"},{"@type":"WebSite","@id":"https:\/\/mariusbancila.ro\/blog\/#website","url":"https:\/\/mariusbancila.ro\/blog\/","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","inLanguage":"en-US","publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Marius Bancila's Blog | About code. Mostly on C++","og:type":"article","og:title":"Virtual inheritance in C++","og:description":"Learn about multiple inheritance in C++, the diamond inheritance problem, and the solution to fix it with virtual inheritance.","og:url":"https:\/\/mariusbancila.ro\/blog\/2021\/11\/16\/virtual-inheritance-in-c\/","article:published_time":"2021-11-16T14:57:21+00:00","article:modified_time":"2021-11-16T20:05:57+00:00","twitter:card":"summary","twitter:title":"Virtual inheritance in C++","twitter:description":"Learn about multiple inheritance in C++, the diamond inheritance problem, and the solution to fix it with virtual inheritance."},"aioseo_meta_data":{"post_id":"4343","title":"Virtual inheritance in C++","description":"Learn about multiple inheritance in C++, the diamond inheritance problem, and the solution to fix it with virtual inheritance.","keywords":[],"keyphrases":{"focus":[],"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":[],"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":{"id":"aioseo-article-6369651305a9f","slug":"article","graphName":"Article","label":"Article","properties":{"type":"BlogPosting","name":"#post_title","headline":"#post_title","description":"#post_excerpt","image":"","keywords":"","author":{"name":"#author_name","url":"#author_url"},"dates":{"include":true,"datePublished":"","dateModified":""}}},"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":"{\"article\":{\"articleType\":\"BlogPosting\"},\"course\":{\"name\":\"\",\"description\":\"\",\"provider\":\"\"},\"faq\":{\"pages\":[]},\"product\":{\"reviews\":[]},\"recipe\":{\"ingredients\":[],\"instructions\":[],\"keywords\":[]},\"software\":{\"reviews\":[],\"operatingSystems\":[]},\"webPage\":{\"webPageType\":\"WebPage\"}}","pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":{"locations":{"business":{"name":"","businessType":"","image":"","areaServed":"","urls":{"website":"","aboutPage":"","contactPage":""},"address":{"streetLine1":"","streetLine2":"","zipCode":"","city":"","state":"","country":"","addressFormat":"#streetLineOne\n#streetLineTwo\n#city, #state #zipCode"},"contact":{"email":"","phone":"","phoneFormatted":"","fax":"","faxFormatted":""},"ids":{"vat":"","tax":"","chamberOfCommerce":""},"payment":{"priceRange":"","currenciesAccepted":"","methods":""}}},"openingHours":{"useDefaults":true,"show":true,"alwaysOpen":false,"use24hFormat":false,"timezone":"","labels":{"closed":"","alwaysOpen":""},"days":{"monday":{"open24h":false,"closed":false,"openTime":"09:00","closeTime":"17:00"},"tuesday":{"open24h":false,"closed":false,"openTime":"09:00","closeTime":"17:00"},"wednesday":{"open24h":false,"closed":false,"openTime":"09:00","closeTime":"17:00"},"thursday":{"open24h":false,"closed":false,"openTime":"09:00","closeTime":"17:00"},"friday":{"open24h":false,"closed":false,"openTime":"09:00","closeTime":"17:00"},"saturday":{"open24h":false,"closed":false,"openTime":"09:00","closeTime":"17:00"},"sunday":{"open24h":false,"closed":false,"openTime":"09:00","closeTime":"17:00"}}}},"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2021-11-16 07:47:16","updated":"2025-12-12 07:56:25","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"author_meta":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"featured_img":null,"jetpack_publicize_connections":[],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"uagb_comment_info":9,"uagb_excerpt":"The C++ language supports the concept of multiple inheritance. This means one class can have multiple base classes. This feature is not available in other languages, such as C# or Java. The designers of these languages didn&#8217;t considered the benefits of supporting this feature to worth the effort. And probably one of the reasons is&hellip;","coauthors":[],"tax_additional":{"categories":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>"]},"tags":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">inheritance<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">virtual<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>","<span class=\"advgb-post-tax-term\">inheritance<\/span>","<span class=\"advgb-post-tax-term\">virtual<\/span>"]}},"comment_count":"9","relative_dates":{"created":"Posted 5 years ago","modified":"Updated 5 years ago"},"absolute_dates":{"created":"Posted on November 16, 2021","modified":"Updated on November 16, 2021"},"absolute_dates_time":{"created":"Posted on November 16, 2021 4:57 pm","modified":"Updated on November 16, 2021 10:05 pm"},"featured_img_caption":"","series_order":"","jetpack_shortlink":"https:\/\/wp.me\/pYNdv-183","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/4343","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/comments?post=4343"}],"version-history":[{"count":12,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/4343\/revisions"}],"predecessor-version":[{"id":4368,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/4343\/revisions\/4368"}],"wp:attachment":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/media?parent=4343"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/categories?post=4343"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/tags?post=4343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}