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

一. 内容

  1. 一旦涉及多重继承,C++社群便分为两个基本阵营。其中之一认为:如果单一继承是好的,多重继承一定更好。另一阵营认为:单一继承是好的,但多重继承不值得拥有。本条款主要目的是让大家了解这两个多重继承的基本观点。

  2. 最先要认清的一件事是:使用多重继承会导致 class 可能从一个以上的 base class 继承相同名称(如函数,变量,typedefs等),那会导致较多的歧义。C++在解析重载函数调用时,会先查找是否具有对此调用匹配的函数,找出最佳匹配后再检验其可取性。这意味着即使在 base class 声明为 private 的函数也会被纳入匹配的范围,导致可能的二义性问题

    为了解决这个歧义,你必须明确指出你要调用哪个 base class 的函数。例如 xxx::yyy()

  3. 多重继承中,如果有一个 derived class 可由 base class 经过多个路径到达,你就必须面对这样一个问题,是否打算让 base class 的成员变量经由每一条路径被复制?比如下面例子:

    在这里插入图片描述
    如果 File 成员每一条到 IOFile 的路径都被复制,意味着 IOFile 将持有两份一模一样的 File 成员。但简单的逻辑告诉我们,这种重复是没有必要的。

    C++ 的默认做法是执行复制。如果你不想要这种复制的默认行为,可以使用 virtual 关键字,使 File 成为 virtual base class。

    在这里插入图片描述

    这样可以保证 IOFile 只会持有一份来自 File 的成员。

  4. 从合理行为的观点来看, public 继承应该总是使用 virtual。这样总是可以保证 derived class 总是不会重复获得成员。但是合理并不是唯一观点,virtual 继承需要付出代价,使用 virtual 继承的那些 class 产生的对象往往比 non-virtual 继承的对象体积大,访问速度慢。种种细节因编译器不同而异,但可以确定一点,你得为此付出代价。

  5. virtual 继承的成本还包括其他方面。比如 virtual class 的初始化责任是由继承体系中最底层的(most derived)class 负责,这暗示 class 若派生自 virtual classes 而需要初始化,必须认识其 virtual class,不论继承体系有多少,且必须负责其所有 virtual class 的初始化责任。

  6. 我对 virtual base classes 的看法很简单:第一,非必要不要使用 virtual classes,平常请使用 non-virtual 继承。第二,如果你必须要使用 virtual base class,请避免在类中放置数据。这样就不必担心 virtual classes 的初始化责任。类似 interfaces 的结构很适合于此。

  7. 那么对于接口和实现分开的设计,多重继承显然就可以发挥其作用。举个 Person class 的简单例子:

    class IPerson {
    public:
        virtual ~IPerson() = default;
        virtual std::string GetName() const =0;
    };
    
    class IPersonImpl {
    public:
        virtual ~IPersonImpl() = default;
        explicit IPersonImpl(std::string InName): Name(std::move(InName)) {}
    
        virtual std::string GetNameImpl() const {
            return Name;
        }
    
    private:
        std::string Name;
    };
    
    class APerson : public IPerson, private IPersonImpl {
    public:
        explicit APerson(const std::string& InName)
            : IPersonImpl(InName) {}
    
        std::string GetName() const override {
            return IPersonImpl::GetNameImpl();
        }
    };
    

    使用 public 继承其接口,private 继承其实现,似乎是再完美不过的一件事。这个例子告诉我们,多重继承也有它的合理用途。

  8. 最后,我想说,多重继承只是面向对象工具箱的一个工具而已。和单一继承相比,它通常比较复杂,使用上也难以理解。所以如果你有个单一继承的方案,也有一个多重继承的方案,那么单一继承的设计方案一定比较受欢迎。然而有时候多重继承确实是完成任务之最简洁,最易维护,最合理的方案,那就别害怕使用它们,只要确定,你的确是在明智而审慎的情况下使用它。

二. 总结

  1. 多重继承比单一继承复杂。它可能导致新的歧义性,以及对 virtual 继承的需要。
  2. virtual 继承会增加大小,速度,初始化(赋值)复杂度等等成本。如果 virtual base classes 不带任何数据,将是最具有实用价值的情况。
  3. 多重继承的确有正当用途。其中一个情节涉及 public 继承某个 Interface class 和 private 继承某个协助实现的 class 的两相组合。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《Effective C++ 第三版》是一本关于C++高效编程的经典书籍,它涵盖了23个关键的C++编程技术,旨在帮助C++程序员成为更加高效和高质量的软件工程师。本书主要聚焦于面向对象编程和模板编程,以及C++语言的一些独特特性和语法,如函数重载、拷贝构造函数、移动语义、虚函数和多重继承等。本书帮助读者了解和掌握如何更好地使用C++,以提高代码的可读性、可维护性和可重用性。本书还覆盖了很多经常出现的编程问题,如内存管理、异常处理、并发编程等等,以及如何进行程序优化和测试。《Effective C++ 第三版》是一本全面而且深入的书籍,可以帮助C++ programmer成为真正的C++专家。无论是入门开发者还是有经验的程序员,都可以从中获得很多价值。此外,《Effective C++ 第三版》也是一本非常好的参考书籍,可以为学习和使用C++提供坚实的理论基础和实用的示例代码。 ### 回答2: "Effective C++" 是著名的程序设计书籍,作者是著名计算机科学家Scott Meyers。该书现已经推出第三版,也有了相应的PDF电子书。 这本书主要介绍了C++语言的一些重要概念和技术,帮助读者更好地理解C++的基本特性和高级编程技巧。第三版对前两版的内容进行了全面更新和完善,加入了最新的C++11和C++14标准中的变化和增强,包含了作者多年的实践和经验总结,增加了大量的实例和代码。 此外,"Effective C++"第三版还介绍了许多经典的C++编程问题和解决方案,例如对象生命周期管理、内存管理、资源共享、模板和STL应用等。这些问题在实际编程中经常会遇到,掌握了这些技巧有助于提升代码的质量、可靠性和效率。 总之,"Effective C++"第三版是一本十分实用、经典的C++编程书籍,它不仅适合初学者,也对有经验的程序员有重要的参考价值。无论是想提高自己的编程水平、规避C++程序中常见的错误,还是想进一步掌握现代C++编程技术的读者,都不可错过这本书。 ### 回答3: Effective C++ 第三版 pdf 是一本非常有价值的书籍,它是由 C++ 大师 Scott Meyers 所著,是 C++程序员必读的一本书籍。本书深入浅出地介绍了 C++语言中的一些非常重要的知识点和技巧,帮助读者更好地理解和运用 C++语言,提高编程的质量和效率。 在 Effective C++ 第三版 pdf 中,作者从多个方面对 C++语言进行了详细分析和解释,包括构造函数和析构函数的实现,运算符重载的使用,继承和虚函数的原理和应用,以及 STL等一系列的 C++语言特性和库函数的使用技巧。通过对这些重要知识点的深入讲解,读者可以很好地掌握 C++语言的内涵和精髓,提高自己的编程能力和技巧。 除此之外,Effective C++ 第三版 pdf 还提供了大量的实例和代码,能够直观地展示作者所说的知识点,并帮助读者更好地理解和掌握 C++语言的实际应用。读者可以通过反复练习和实践,逐渐掌握 C++语言的精髓和技巧,并能够应用到实际开发中,提高自己的编程能力和水平。 总之,Effective C++ 第三版 pdf 是一本非常有价值的书籍,它涵盖了 C++语言的重要知识点和技巧,同时提供了大量的实例和代码,能够帮助读者全面掌握 C++语言,提高自己的编程能力和水平。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值