前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >EasyC++86,多继承(一)

EasyC++86,多继承(一)

作者头像
TechFlow-承志
发布2022-08-26 18:03:03
1560
发布2022-08-26 18:03:03
举报
文章被收录于专栏:TechFlowTechFlow

作者 | 梁唐

大家好,我是梁唐。

是的,我还没有弃坑,这是EasyC++系列的第86篇,来聊聊多继承

多继承(一)

C++支持多继承,即允许一个类同时继承多个类。

关于多继承,一直以来争议不断,有一部分人认为多继承会带来大量的问题,为了解决这些问题会使得语言本身变得非常复杂,因此应当避免。另外一派认为多继承在某些场景下可以起到非常关键的作用,应当予以支持。

关于多重继承是好是坏,这是一个非常复杂的问题,网上历来争议不断。因此不过多阐述,感兴趣的同学可以查阅一下相关资料。仅仅从实际支持来看,目前市面上大部分的语言包括Java仅支持单继承,只有C++等少数语言支持多继承。这和C++的理念也有关,即认定不能通过减少语言特性来增强语言的表达力。

看完争议之后,我们来看看究竟什么是多继承呢?

我们来看一段代码案例:

代码语言:javascript
复制
class A{
public:
    void funcA();
};

class B{
private:
    bool funcB() const;
};

class C: public A, public B{ ... };

在这段代码当中我们定义了两个类A和B,然后我们创建了一个类C,同时继承了A和B。这就是多继承,这里要注意一点,我们必须用关键字public来限定每一个基类,否则的话编译器会默认这是一个私有继承。

如果我们稍微修改一下代码,就会出现一些问题,比如:

代码语言:javascript
复制
class A{
public:
    void func();
};

class B{
private:
    bool func() const;
};

class C: public A, public B{ ... };

在上面这个例子当中A和B都包含了函数func,在下面的执行语句当中会报错。

代码语言:javascript
复制
C c;
c.func();

虽然B中的func函数是私有的,但对于编译器来说依然是有歧义的。如果想要消除歧义,我们可以这样调用c.A::func()

当多继承的父类拥有更高的继承层级的时候,可能会出现更复杂的问题,比如多继承菱形。也就是多个类之间的继承关系构成了一个抽象意义上的菱形,比如我们参考一下C++ Primer中的例子:

在上面这张图当中,Singer和Waiter都继承了Worker,而SingingWaiter同时继承了Singer和Waiter。从图上来看,这似乎没什么问题,但在实现上问题不少。

比如说,对于SingingWaiter类来说,它当中包含了多少Worker呢?

答案是有两个,从Singer这边继承了一个Worker,从Waiter又继承了一个Worker。那么我们这样写就会出现问题:

代码语言:javascript
复制
SingingWaiter sw;
Worker *p = &sw;

通常这种赋值的时候,会将基类指针设置成派生类中基类对象的地址,但由于sw对象当中包含两个Worker对象,有两个地址,所以也会导致歧义。我们可以使用强制转换的方式消除歧义:

代码语言:javascript
复制
SingingWaiter sw;
Worker *p = (Singer*) &sw;
Worker *p = (Waiter*) &sw;

但显然这样的方法虽然能够解决问题,但是非常的丑陋。我们还有更好的方法,会在下一篇文章和大家分享。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-03-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Coder梁 微信公众号,前往查看

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

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

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