前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >多继承三角和钻石问题(虚继承)

多继承三角和钻石问题(虚继承)

作者头像
我与梦想有个约会
发布2023-10-20 16:43:07
1610
发布2023-10-20 16:43:07
举报
文章被收录于专栏:jiajia_deng

上一篇文章我们简单介绍了一下多继承的语法,但是我们遇到了一个问题,那就是如果多个父类具有相同名称的成员变量或成员方法,子类在调用的时候就会出现二义性问题,子类不知道选择哪一个父类的变量或方法,我们称之为三角问题。如下所示:

所以在编译的时候程序就无法通过了。其实解决这个问题有很多办法,先说一个最简单的办法就是使用域运算符,直接使用某个父类的成员函数或变量。如下所示:

代码语言:javascript
复制
#include 
using namespace std;
class Bed
{
public:
void sleep()
{
cout << “Bed Sleep ~~” << endl;
}
protected:
int data;
};
class Sofa
{
public:
void sit()
{
cout << “Sofa sit ~~” << endl;
}
protected:
int data;
};
// 继承多个父类
class Derive : public Bed, public Sofa
{
public:
Derive()
:Bed(), Sofa() {}
void display()
{
// 使用作用域运算符,直接指定调用某个父类的成员
cout << Bed::data << endl;
cout << Sofa::data << endl;
}
};
int main(int argc, char* argv[])
{
Derive SofaBed;
SofaBed.sleep();
SofaBed.sit();
SofaBed.display();
return 0;
}

这是一种解决办法,当然,本文介绍的绝不止这些。在设计类的过程中,如果多个父类出现了同名的公有成员变量或方法,并且方法所执行的认为是一模一样的情况下,这证明我们设计的类是有问题的,应该保证实现同一功能的方法只有一个。那在上面的案例中我们需要抽象出一个基类,这个基类将Sofa和Bed两个类的公有同名变量或成员存放到基类中,然后让 Sofa 和 Bed 使用虚继承的方式,继承这个基类,这时,子类再多继承 Sofa 和 Bed 类的时候,就不会出现二义性问题了。其中 虚继承 起到了重要的作用,他让基类派生的两个类只保留了一份共有公共成员,这种情况,我们称之为钻石问题。

代码语言:javascript
复制
#include 
using namespace std;
class M
{
public:
int data;
};
// 虚继承 M 类
class Bed : virtual public M
{
public:
void sleep()
{
cout << “Bed Sleep ~~” << endl;
}
};
// 虚继承 M 类
class Sofa : virtual public M
{
public:
void sit()
{
cout << “Sofa sit ~~” << endl;
}
};
// 继承多个父类
class Derive : public Bed, public Sofa
{
public:
Derive()
:Bed(), Sofa() {}
void display()
{
// 无需再担心二义性问题
cout << data << endl;
}
};
int main(int argc, char* argv[])
{
Derive SofaBed;
SofaBed.sleep();
SofaBed.sit();
SofaBed.display();
return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档