栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

[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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/347491.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号