PrevUpHome

day-14: 15 Minutes c++ Virtual Inheritance


Virtual Inheritance

virtual inheritance declaration:

class derived_class: virtual public base_class	// virtual inheritance
{
};

Why

Let us see a program that does not use virtual inheritance.

// A maybe-issue or maybe-not-issue program.

#include <iostream>

class base_base
{
public:
	base_base() {std::cout << "0\n";}
	virtual ~base_base() {std::cout << "~0\n";}
};

class derived_a: public base_base	// non-virtual inheritance
{
public:
	derived_a() {std::cout << "1\n";}
	~derived_a() {std::cout << "~1\n";}
};

class derived_b: public base_base	// non-virtual inheritance
{
public:
	derived_b() {std::cout << "2\n";}
	~derived_b() {std::cout << "~2\n";}
};

class derived_z: public derived_a, public derived_b	// non-virtual inheritance
{
public:
	derived_z() {std::cout << "z\n";}
	~derived_z() {std::cout << "~z\n";}
};

int main()
{
	derived_z z_obj{};
	std::cout << "----------------------------------------" << std::endl;
}

Compile & Run

Compile and run the code:

>>>  g++ hello.cpp -std=c++23 -o hello
>>>  ./hello
0
1
0
2
z
----------------------------------------
~z
~2
~0
~1
~0

Read the output information carefully, you will notice that,

The object of base_base is constructed twice, (output two 0),
and destructed twice (output two ~0) .

The object creation and destroying for base_base is performanced twice, it is duplicated.

Speaking honestly, the above described issue might be an issue, might be not an issue. Anyway, the duplicated creation and destroying portion still work.

Another

However, it has another issue, now create a pointer of type base_base, and let it point to derived_z:

base_base * ptr = new derived_z;

delete ptr;

The compiling report errors:

hello.cpp: In function ‘int main()’:
hello.cpp:33:31: error: ‘base_base’ is an ambiguous base of ‘derived_z’
   33 |         base_base * ptr = new derived_z;
      |                               ^~~~~~~~~

Solution: Virtual Inheritance

Add a virtual specifier to the inheritance is the solution: virtual inheritance.

class base_base {};
class derived_a: virtual public base_base {};
class derived_b: virtual public base_base {};
class derived_z: public derived_a, public derived_b {};

Where to put the specifier virtual :

Put the virtual between derived_a or derived_b and base_base, because the same base_base is shared to the derived classes via two routines.

After adding virtual to inheritance, the two issues are solved:

  1. base_base creation and destroying are not duplicated.
  2. Pointer pointing from type base_base to type derived_z work:

    base_base * ptr = new derived_z{};







Written on Nov 05, 2024

Back

Up: day-14

Index

cpp/c++

c++ std::exception:

std::cout.write(err.data(), err.size());

std::cout << std::endl;

caught:

  ==================================================
  #        The c++ programming language.           #
  #                                                #
  #        Home: cppfx.xyz                         #
  #        E                                       #
  #        Join c++ Discord: yZcauUAUyC            #
  #        Deck                                    #
  ==================================================

PrevUpHome