Inheritance ambiguity problem in diamond inheritance in C++

Inheritance ambiguity problem in diamond inheritance in C++

class A
{
public:
	virtual void func1()
	{
		cout << "A::func1()" << endl;
	}

	int _a;
};

class B:virtual public A 
{
public:
	virtual void func1()
	{
		cout << "B::func1()" << endl;
	}

	int _b;
};

class C:virtual public A
{
public:
	virtual void func1()
	{
		cout << "C::func1()" << endl;
	}

	int _c;
};

class D:public B,public C
{
public:
	int _d;
};

int main(void)
{
	D d;
	return 0;
}

This code will directly report an error.

So why?

Because both B and C are virtual inheritance from A, it is mainly used to solve data redundancy, but this will result in only one instance of A when D is created, and because D is multiple inheritance, inheriting B and C, so in D There are two virtual function tables in it , but because both B and C have rewritten func1 in A, it will eventually lead to ambiguity if D calls func1() and does not know which one to call.

Virtual inheritance will allow subclasses to share an instance of the base class, avoiding multiple copies of the base class in the subclass

If there are three classes ABC, B and C virtual inheritance of A, if B and C respectively rewrite the test() in A, will this test no longer be shared after rewriting, and the others will still be shared.

If class B and class C rewrite the virtual function test() in class A respectively, then this function is no longer shared, but exists in the respective implementations in the virtual function tables of class B and class C. At this time, when this function is called in class D, the implementations in class B and class C need to be called respectively according to the needs, but the implementation in class A cannot be called directly.

Other virtual functions are still shared, because virtual inheritance will make class B and class C share the same instance of class A, including other virtual functions in class A. Virtual inheritance only affects the layout and storage of the base class in the derived class, and does not affect the rewriting behavior of the function. The rewriting behavior of the function is based on the matching of the function name and the parameter list, and has nothing to do with virtual inheritance. So if class B and class C don't override other virtual functions in class A, those functions will still be shared.

class A
{
public:
	virtual void func1()
	{
		cout << "A::func1()" << endl;
	}

	int _a;
};

class B:virtual public A 
{
public:
	virtual void func1()
	{
		cout << "B::func1()" << endl;
	}

	int _b;
};

class C:virtual public A
{
public:
	virtual void func1()
	{
		cout << "C::func1()" << endl;
	}

	int _c;
};

class D:public B,public C
{
public:
	virtual void func1()
	{
		cout << "D::func1()" << endl;
	}
	
	int _d;
};

The correct code should be like this, but it is generally not recommended to use diamond inheritance, which will be particularly troublesome, so don’t use it if you can.

Guess you like

Origin blog.csdn.net/AkieMo/article/details/131742525