首页 > 编程语言 >Effective C++ 条款40:明智而审慎地使用多重继承

Effective C++ 条款40:明智而审慎地使用多重继承

时间:2024-12-30 16:27:17浏览次数:3  
标签:多重 Effective 继承 class C++ public 40 display 歧义

文章目录

条款40:明智而审慎地使用多重继承

多重继承(Multiple Inheritance)允许一个类从多个基类继承。然而,与单一继承相比,多重继承更加复杂,可能带来以下问题和成本:

  1. 歧义性:当多个基类中存在相同名称的成员时,派生类的调用可能产生歧义。
  2. 对 virtual 继承的需求:为了避免重复继承的问题(如菱形继承),需要引入虚继承,但这会增加运行时的开销。
  3. 额外的开销:虚继承可能导致类的大小增加、访问速度下降,以及初始化和赋值的复杂度提高。

尽管多重继承复杂,但在某些情况下它是合理的选择,尤其是涉及以下场景:

  • Interface class 的公共继承。
  • 协助实现的类的私有继承。

示例 1:多重继承中的歧义

class Base1 {
public:
    void display() const {
        std::cout << "Base1::display" << std::endl;
    }
};

class Base2 {
public:
    void display() const {
        std::cout << "Base2::display" << std::endl;
    }
};

class Derived : public Base1, public Base2 {
};

int main() {
    Derived d;
    // d.display(); // 错误:不明确,Base1 和 Base2 中都有 display
    d.Base1::display(); // 明确调用 Base1 的 display
    d.Base2::display(); // 明确调用 Base2 的 display
    return 0;
}

在多重继承中,派生类可能继承多个基类中同名的成员函数。这种情况下,调用成员函数会产生歧义,必须明确指定调用哪一个基类的函数。


示例 2:避免菱形继承问题

菱形继承 问题发生在一个派生类通过不同的路径多次继承同一个基类:

class Base {
public:
    virtual void display() const {
        std::cout << "Base::display" << std::endl;
    }
};

class Derived1 : public virtual Base {};
class Derived2 : public virtual Base {};

class MostDerived : public Derived1, public Derived2 {};

int main() {
    MostDerived md;
    md.display(); // 没有歧义,只有一个 Base 子对象
    return 0;
}

通过使用 virtual 继承MostDerived 类可以确保只有一个 Base 子对象存在,避免了菱形继承的歧义。


示例 3:合理使用多重继承

一个合理的多重继承设计可能是将 接口继承实现继承 结合起来:

class Interface {
public:
    virtual void process() const = 0; // 纯虚函数,提供接口
};

class Helper {
protected:
    void assist() const {
        std::cout << "Helper::assist" << std::endl;
    }
};

class Derived : public Interface, private Helper {
public:
    virtual void process() const override {
        assist(); // 调用 Helper 提供的功能
        std::cout << "Derived::process" << std::endl;
    }
};

int main() {
    Derived d;
    d.process();
    return 0;
}

在这个例子中,Derived 类通过 public 继承 获得 Interface 的接口,通过 private 继承 使用 Helper 提供的实现。


总结

  • 多重继承增加了复杂性,但在某些场景下是必要的。
  • 虚继承 可以解决菱形继承问题,但也带来了额外的开销。
  • 一个常见的合理用法是 公共继承接口类私有继承实现类 的组合。
  • 在设计中尽量避免过度使用多重继承,如果可以,用 复合 替代复杂的继承关系。

标签:多重,Effective,继承,class,C++,public,40,display,歧义
From: https://blog.csdn.net/weixin_42255569/article/details/144825421

相关文章

  • C12.【C++ Cont】string类字符串的创建、输入、访问和size函数
    目录1.概念2.string字符串的创建示例代码 运行结果备注 2.string字符串的输入1.cin(字符串没有空格)2.getline(可以读含有空格的字符串)示例代码1:getline传两个参数示例代码2:getline传三个参数3.size函数示例代码运行结果4.访问string类字符串示例代码 运......
  • 1. C++快速入门--变量和基本类型, 类别
    文章使用obsidian编写,双链部分可能失效1基本内置类型1.1算术类型算术类型介绍bool类型字符类型整数类型实数浮点、虚数浮点和复数浮点参看如下表![[Pastedimage20230814160130.png|700]]带符号和无符号类型的变量分为:signed和unsignedunsigned变量......
  • 每天40分玩转Django:Django REST框架学习指南
    DjangoREST框架学习指南一、今日学习内容概览知识模块重点内容序列化(Serialization)模型序列化、验证器、嵌套序列化视图集(ViewSets)模型视图集、只读视图集、CRUD操作路由(Routing)自动URL路由、自定义路由、嵌套路由二、详细内容讲解1.序列化(Serialization)序列......
  • 每天40分玩转Django:Django Channels
    DjangoChannels一、今日学习内容概览知识模块重点内容难度系数WebSocket基础WebSocket协议、连接建立、消息传输★★★★☆消息路由URL路由配置、消费者编写、消息处理★★★★☆Channels配置项目配置、ASGI应用、ChannelLayers★★★☆☆二、WebSocket基础1.环境配......
  • qt/c++ 学习笔记之网页照片爬虫
    *注意:本爬虫使用的qt版本为5.14.2,使用的是qtwebkit类是自己配置了qtwebkit和对应qt版本的openssl,其中qtwebkit类在qt5.15和qt6版本已经删除,需要自己私下配置qtwebkit和对应qt版本的openssl头文件widget.h#ifndefWIDGET_H#defineWIDGET_H#include<QWidget>#include......
  • 408数据结构—顺序表和链表
    一、写在最前线性表是一种逻辑结构,表示元素之间一对一的相邻关系,同时还有非线性表顺序表和链表是存储结构,两者属于不同层面的概念我们可以用顺序表和链表实现线性表线性表:个数有限,相同类型,有先后次序(前驱后驱)二、顺序表定义线性表的顺序存储又称顺序表。它是用一组......
  • 408数据结构—时间复杂度的计算
    算法效率的度量是通过时间复杂度和空间复杂度来描述的。时间复杂度在统考中是一大重点,在算法设计题里通常都会要求分析时间复杂度,空间复杂度,同时还会出现考察时间复杂度的选择题,所以需要考生熟练掌握一、时间复杂度频度:一个语句的频度是指该语句在算法中被重复执行的次数......
  • 2024-2025-1 20241406刘书含 第十四周学习总结
    一、教材学习内容(一)第十四章模拟、图形学、游戏以及其他应用《计算机科学概论》第十四章主要探讨了模拟、图形学、游戏以及其他应用。以下是该章节的总结:模拟:模拟是计算的一个重要领域,它涉及为复杂系统构建计算机模型,并用模型进行实验以观察结果。模型是对真实系统的抽象,系统......
  • C++关键字
    C++关键字static类和结构体外的static被static修饰后只在内部发生链接,其作用域只在其所在的文件中。类和结构体内的staticstructEntity{ staticintx,y; 静态成员变量 staticvoidPrint() { std::cout<<x<<","<<y<<std::endl; }};intEntity::x; //......
  • 2024-2025-1 20241409 《计算机基础与程序设计》第四周学习总结
    作业信息作业归属课程:https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP作业要求:https://www.cnblogs.com/rocedu/p/9577842.html#WEEK04作业目标:门电路;组合电路,逻辑电路;冯诺依曼结构;CPU,内存,IO管理;嵌入式系统,并行结构;物理安全作业正文:教材学习内容总结《计算机科学概......