C++入门多继承(菱形继承)及其二义性问题
Posted 正在起飞的蜗牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++入门多继承(菱形继承)及其二义性问题相关的知识,希望对你有一定的参考价值。
1、二义性问题
1.1、示例代码
#include <iostream>
#include <string>
using namespace std;
class A
public:
void speak(void);
;
class B
public:
void speak(void);
;
class C:public A, public B
public:
;
int main(void)
C variable;
variable.speak(); //使用speak成员时存在二义性问题,编译报错
//variable.A::speak(); //明确指定,没有歧义
//variable.B::speak(); //明确指定,没有歧义
return 0;
void A::speak()
cout << "A::speak" << endl;
void B::speak()
cout << "B::speak" << endl;
1.2、代码分析
root@ubuntu:# g++ test.cpp -o app --std=c++11
test.cpp: In function ‘int main()’:
test.cpp:31:11: error: request for member ‘speak’ is ambiguous
variable.speak();
test.cpp:15:7: note: candidates are: void B::speak()
void speak(void);
test.cpp:9:7: note: void A::speak()
void speak(void);
make: *** [all] Error 1
(1)在A和B类中存在同名的speak成员;
(2)C同时继承A和B两个类,此时C中存在两个不同命名空间但是同名的成员(speak),当C类的对象使用speak成员时,编译器不知道该使用A类的speak,还是B类的speak;
2、解决二义性的方法
(1)解决办法1:避免出现,让A和B的public成员命名不要重复冲突。但这个有时不可控。
(2)解决办法2:编码时明确指定要调用哪一个,用variable.A::speak()明确指定调用的是class A的speak而不是class B的
(3)解决办法3:在C中重定义speak,则调用时会调用C中的speak,A和B中的都被隐藏了;
补充:对C++的隐藏特性不清楚的可以查看博客:《【C++入门】访问权限管控和继承机制详解》;
3、菱形继承问题
3.1、产生菱形继承问题的原因
(1)产生菱形继承的原因如上图,C继承A和B,但是A和B都继承Base类,于是A和B都各自有一份Base类的成员;
(2)当C继承A和B时,此时C中就有两份Base类的成员,于是就产生了歧义;如果C类中使用Base类的成员,就不知道使用A中的那份还是B中的那份;
3.2、示例代码
#include <iostream>
#include <string>
using namespace std;
class Base
public:
int dataBase;
;
class A: public Base
public:
int dataA;
;
class B: public Base
public:
int dataB;
;
class C:public A,public B
public:
int dataC;
;
int main(void)
C param;
param.dataBase; //产生歧义
return 0;
3.3、示例代码分析
[root@]$ g++ main.cpp -o app --std=c++11
main.cpp: In function ‘int main()’:
main.cpp:39:8: error: request for member ‘dataBase’ is ambiguous
param.dataBase;
^
main.cpp:10:6: note: candidates are: int Base::dataBase
int dataBase;
^
main.cpp:10:6: note: int Base::dataBase
make: *** [all] Error 1
C类对象在使用dataBase成员时,不知道使用A类中的dataBase,还是B中的dataBase,产生歧义,于是编译报错;
3.4、虚继承解决菱形继承问题
3.4.1、示例代码
#include <iostream>
#include <string>
using namespace std;
class Base
public:
int dataBase;
;
class A: virtual public Base //virtual:表示虚继承
public:
int dataA;
;
class B: virtual public Base //virtual:表示虚继承
public:
int dataB;
;
class C:public A,public B
public:
int dataC;
;
int main(void)
C param;
param.dataBase = 1;
cout << "param.dataBase=" << param.dataBase << endl;
return 0;
使用virtual关键字,让A和B都虚继承Base类;
3.4.2、虚继承实现的原理
实现原理参考博客:《【C++入门】虚继承的实现原理》;
推荐
我会在C++专栏持续根据更新C++相关的知识点,这里也给大家推荐一款学习C++的神器,我也是在用这一款神器在学习C++。
链接:学习神器跳转
如果你是想入门C++这门语言或者是找C++岗位的工作,都推荐你试试这个网站,里面有针对C++知识点的选择题、编程题,更有C++岗位的面试题,还可以在里面交流行业信息
以上是关于C++入门多继承(菱形继承)及其二义性问题的主要内容,如果未能解决你的问题,请参考以下文章