C++学习笔记:多继承及其二义性问题、虚继承
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C++学习笔记:多继承及其二义性问题、虚继承,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2986字,纯文字阅读大概需要5分钟。
内容图文
C++学习笔记:多继承及其二义性问题
1.多继承
多继承就是一个子类有多个父类。
在继承中,子类会继承父类的成员变量和成员函数:
class A
{
public:
int a;
void print(void){cout<<"a = "<<this->a<<endl;}
};
class C:public A
{};
int main(int argc,char**argv)
{
C c;
c.a=5;
c.print();
return 0;
}
输出:
a = 5
上面是单继承的情况,C类很好继承了A类的print()
方法,多继承和单继承的原理、效果并无明显区别,但是多继承会导致二义性问题,来看这样一种情况,假如C类继承自A类和B类,且B类中也有一个print()
方法,这个时候C该继承哪一个呢?
不妨写代码测试一下:
class A
{
public:
int a;
void print(void){cout<<"a = "<<this->a<<endl;}
};
class B
{
public:
int b;
void print(void){cout<<"b = "<<this->b<<endl;}
};
class C:public A,public B
{
};
int main(int argc,char**argv)
{
C c;
c.a=5;
c.print();
return 0;
}
结果是编译报错了,对于编译器来说,print()
是模糊有歧义的:
main.cpp:98:4: error: request for member ‘print’ is ambiguous
c.print();
多继承的二义性问题有2种情况。
2.多继承的二义性问题情况1
场景1:C多继承自A和B,则C中调用A和B的同名成员时会有二义性。
原因分析:C从A和B各自继承了一个同名(但是不同namespace
域)成员,所以用C的对象来调用时编译器无法确定到底想调用的是哪一个。
解决办法:
- ①避免出现同名方法,让A和B的
public
成员命名不要重复冲突。但这个有时不可控,比如A和B类都是别人提供的,当另外的人使用C类想继承A,B两个类的时候,还得去找提供这个两个类的人,你俩谁行行好,把print()
重命名一下。 - ②编码时明确指定要调用哪一个,用
c.A::print()
明确指定调用的是A的print()
而不是B的,这就类似于2个人叫张三,在外面高的就叫大张三,矮的叫小张三。 - ③在C中重定义
print()
,则调用时会调用C中的print()
,A和B中的都被隐藏了。
总结:能解决,但是都没有很好的解决。
3.多继承的二义性问题情况2
场景2:菱形继承问题。即A为祖类,B1:A, B2:A, C:B1,B2,此时用C的对象调用A中的某个方法时会有二义性。
原因分析:c.print()
有二义性,c.A::print()
也有二义性,但是c.B1::print()
和c.B2::print()
却没有二义性。
解决办法:和情况1中的一样,但是情况2更隐蔽,也更难以避免。
4.多继承的二义性问题情况总结
二义性就是歧义,好的情况表现为编译错误,不好的情况表现为运行时错误,最惨的情况表现为运行时莫名其妙.随着系统规模的变大和逻辑变复杂,难免出现二义性,这是系统自身带来的。
解决二义性问题不能靠写代码的人个人的细心和调试能力,而要靠机制,也就是编程语言的更高级语法特性。虚函数、虚继承、纯虚函数、抽象类、重写覆盖、多态等概念就是干这些事的。
5.虚继承解决菱形继承的二义性问题
5.1 虚继承怎么用
场景:菱形继承导致二义性问题,本质上是在孙子类C中有B1和B2中包含的2份A对象,所以有了二义性。
虚继承解决方案:让B1和B2虚继承A,C再正常多继承B1和B2即可。
class A
{
public:
int a;
void print(void){cout<<"a = "<<this->a<<endl;}
};
class B1:virtual public A
{
//A::print()
};
class B2:virtual public A
{
//A::print()
};
class C:public B1,public B2
{
//B1::A::print()
//B2::A::print()
};
虚继承就这么简单,就是为了解决菱形继承的二义性问题而生,和虚函数(为了实现多态特性)并没有直接关系。
5.2 虚继承的实现原理
虚继承的原理是:虚基类表指针vbptr
和虚基类表virtual table
。
内容总结
以上是互联网集市为您收集整理的C++学习笔记:多继承及其二义性问题、虚继承全部内容,希望文章能够帮你解决C++学习笔记:多继承及其二义性问题、虚继承所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。