[C++]多继承与二义性问题

[C++]多继承与二义性问题,第1张

[C++]多继承与二义性问题

1. 什么是多继承?

多继承就是一个子类有多个父类,如下代码示例。

class C:public A, public B
{
};

2. 多继承会导致二义性问题

(1)场景1:多继承的二义性

C多继承自A和B,则C中调用A和B的同名成员时会有二义性。

原因:C从A和B各自继承了一个同名(不同namespace域)成员,所以用C的对象来调用时编译器无法确定我们想调用的是哪一个。

//基类 A
class A{
public:
    void set(int a);
};

//基类 B
class B{
public:
    void set(int a);
};

//派生类 C
class C:public A, public B
{
}

// main.cpp
int main()
{
    c.set();    //编译报错,set()有二义性,编译器不知其来自A还是来自B
}


解决方法:

解决办法1:避免出现,让A和B的public成员命名不要重复冲突。但这个有时不可控。

解决办法2:编码时明确指定要调用哪一个,用 c.A::func() 明确指定调用的是 class A 的 func 而不是 class B 的。

解决办法3:在 C 中重定义 func,则调用时会调用 C 中的 func,A 和 B 中的都被隐藏了。

(2)场景2:菱形继承问题

 即A为祖类,B1:A, B2:A, C:B1,B2,此时用C的对象调用A中的某个方法时会有二义性。

分析:c.func()有二义性,c.A::func()也有二义性,但是c.B1::func()和c.B2::func()却没有二义性。

解决办法:和问题1中的一样,但是问题2更隐蔽,也更难以避免。

3. 虚继承解决菱形继承的二义性问题

菱形继承导致二义性问题,本质上是在孙子类C中有B1和B2中包含的2份A对象,所以有了二义性。

虚继承解决方案:让B1和B2虚继承A,C再正常多继承B1和B2即可。

class B1: virtual public A
{
	// A::set
};

class B2:virtual public A
{
	// A::set
};

class D:public B1, public B2
{
	// B1,B2为虚继承A,则D继承B1, B2时,只会继承了一个A类的函数,C++天然地优化掉其中一个A类的函数
};

4. 虚继承的实现原理

虚继承的原理是:虚基类表指针vbptr和虚基类表virtual table

参考:https://blog.csdn.net/xiejingfa/article/details/48028491

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/4751992.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-11-08
下一篇2022-11-08

发表评论

登录后才能评论

评论列表(0条)

    保存