【问题标题】:C++ - Multiple InheritanceC++ - 多重继承
【发布时间】:2012-01-31 12:35:05
【问题描述】:

我有一个要求,它将形成钻石恐惧图案。但是我从堆栈溢出伙伴那里遇到了 cmets,如果虚拟基类是纯抽象类,那么菱形图案就不是那么重要了。有人可以详细说明为什么会这样吗?

【问题讨论】:

    标签: c++


    【解决方案1】:

    C++ 中的多重继承是一个强大但棘手的工具,如果不小心使用,通常会导致问题。

    以下文章将教您如何使用虚拟继承来解决程序员遇到的一些常见问题。

    Solving the Diamond Problem with Virtual Inheritance

    尝试如下实现dimond:文章给出了很好的解释

    class storable 
    {
            public:
            storable(const char*);
            virtual void read()=0; //this becomes pure virtual making storable an abstract
            virtual void write(); //class
            virtual ~storable();
            private:
            ....
    }
    
    class transmitter: public virtual storable 
    {
            public:
            void write()
            {
                    read();
                    ....
            }
    } 
    
    class receiver: public virtual storable
    {
            public:
            void read();
    }
    
    class radio: public transmitter, public receiver
    {
            public:
            ...
    }
    
    int main()
    {
            radio *rad = new radio();
            receiver *r1 = rad;
            transmitter *r2 =rad;
    
            rad->write();
            r1->write();
            r2->write();
            return 1;
    }
    

    【讨论】:

      【解决方案2】:

      我不确定您对虚拟继承或菱形图案了解或不了解多少。简单的答案是,如果继承不是虚拟的(从菱形的根开始),那么您将拥有 V,而不是菱形,其中完整类型包含 两个 基类的独立副本。虚拟继承基本上是告诉编译器您只需要完整类型(大多数派生)中的基类副本,而不管有多少中间类型在其继承关系中将该基类称为虚拟。

      当然,这种方法会带来自己的问题,例如封装被某种方式破坏(派生类型必须知道 is 基础相对于它们的虚拟基础的继承关系为了调用构造函数),并且对虚拟基础子对象的操作会更加复杂和昂贵。

      【讨论】:

      • 通常,虚拟基础是抽象类,没有数据成员,因此只有一个(机器生成的)默认构造函数。可能有极少数例外,但除此之外,派生类的作者无需了解虚拟继承。
      • @JamesKanze:老实说,我只见过几次使用的虚拟基础,虽然有些确实符合您所说的(纯抽象类),但在其他一些情况下却不是。同样,我对虚拟基类的经验非常有限。
      • 我认为这在很大程度上取决于应用程序。我见过一些广泛使用它们的应用程序。其他人少得多,或者根本没有。 (我也看到过大量滥用它们的应用程序。)一般来说,在它们被充分利用的地方,带有数据的虚拟库很少见(而且主要是在机器生成的代码中)。
      • 我想答案是即使虚拟基本身是一个没有成员数据的纯抽象类,您仍然可能不想删除从虚拟基派生的类中的虚拟继承。您可以使用完全限定名称来解决出现的任何歧义。请参考链接[链接](parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.11}
      【解决方案3】:

      看看这个链接 - How can I avoid the Diamond of Death when using multiple inheritance?

      我相信 cmets 会让您对此有所了解

      【讨论】:

        猜你喜欢
        • 2017-03-31
        • 2012-05-14
        • 2013-08-28
        • 2011-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-10
        相关资源
        最近更新 更多