代码之家  ›  专栏  ›  技术社区  ›  Jeff L

何时多重继承可能是唯一合理的解决方案?[关闭]

  •  9
  • Jeff L  · 技术社区  · 15 年前

    明确地说,我不是在问多重继承是好是坏。我听到了辩论双方的许多争论。

    我想知道在C++中是否存在任何一种设计问题或场景,其中多重继承是完成某件事的唯一途径,或者至少是在所有其他替代方案中最理想的方式,即考虑其他事情是没有意义的。

    显然,这个问题不适用于不支持多重继承的语言。

    10 回复  |  直到 15 年前
        1
  •  10
  •   GManNickG    15 年前

    你做不到 policy-based design 没有多重继承。因此,如果基于策略的设计是解决问题最优雅的方法,那么这意味着您需要多个继承来解决问题,而不是所有其他选项。

    如果多重继承没有被误用(就像任何语言中的所有东西一样),它可能非常有用。

        2
  •  5
  •   Janusz Daniel Rindt    15 年前

    有一种情况,你可以从一个类继承,也许在Java中实现一个或两个接口。这是你想用C++中的多重继承来解决的问题。

        3
  •  3
  •   GalacticCowboy    15 年前

    如果需要继承,多重继承很有用 行为 不仅仅是 合同 .然而,正如其他语言所证明的那样,多重继承并不是解决这个问题的唯一方法,代价是让继承树更深入。因此,在 必须 可能只有 使用多重继承将非常罕见。

        4
  •  3
  •   Steve Jessop    15 年前

    C++流使用多重继承: istream ostream 都是的父母 iostream . 因为他们都继承自 ios_base 你有一颗钻石。

    这是唯一“合理”的解决方案,因为对于标准库的流部分来说,与算法和集合采用相同的行是不合理的。所以Ostream的行为是多态的,而不是像迭代器那样的“duck-typed”接口。

    一旦有了动态多态性,就需要多个继承来同时实现多个接口。

    (*)这大概是因为其他任何事情都会是一场混乱。您必须能够编写操作流的实际函数,而不是强制用户在任何地方都有模板。这是因为写入“某些流,直到运行时才知道是什么”是很常见的,但不想操作“某些集合,直到运行时才知道是什么”。

        5
  •  2
  •   SilentW    15 年前

    我会在Java界面上阅读,等等,以便更好地了解这个问题的答案。接口背后的想法是创建一个抽象类,作为另一个类的模板。这里的优点是模板可以在一个具体的类中组合。例如-

    父类-食品店 子类-咖啡厅 子类-面包房

    有了这个继承树,食品店可以是面包店或咖啡店,但不能两者兼而有之。但是我们怎么称呼星巴克呢?

    更好的办法,伊莫-

    父类-食品店 接口-咖啡厅 界面-面包店

    公共类星巴克扩展食品店实现咖啡店、面包店…}

    你必须了解一点Java才能理解这一点,但必须了解它。接口是相当基本的,IMO。

    作为进一步的思考,也许接口是为服从“不要重复你自己”而设计的。

        6
  •  1
  •   Motti    15 年前

    当您希望继承功能而不是角色时,请举例说明 boost::noncopyable (支持Java的其他语言(与Java语言不同)称为 混合蛋白 )

        7
  •  0
  •   e.tadeu    15 年前

    如其他答案所述:

    而且:

        8
  •  0
  •   Thomas L Holaday    15 年前

    当您必须组合两个或多个第三方类层次结构时,每一个层次结构都要求从层次结构自己的基类派生对象,那么缺少多个继承将使代码变得复杂和复杂。

    namespace Object_Database {
        class Object {
          public:
            virtual void store() ;
            virtual void fetch() ;
        };
    }
    
    namespace Reflectives {
        class Object {
          public:
            virtual std::vector<std::string> > membernames();
            virtual std::vector<std::string> > methodnames();
        };
    }
    

    第一个层次结构允许用户创建可以序列化到对象数据库或从对象数据库序列化的对象,并要求所有此类对象都从类对象_database::object派生。第二个层次结构允许用户创建可在运行时查询其成员名称的对象,并要求所有此类对象都从Reflectives::Object派生。

    如果需要可以同时执行这两种操作的对象,只需编写:

      class ReflectivePickle : 
      public Object_Database::Object, 
      public Reflectives::Object {
        // ...
      };
    

    其他的解决办法是不合理的。

        9
  •  0
  •   Dan    15 年前

    在基类是“接口类”时,我倾向于使用多重继承,即基础类,其中所有的方法都是纯虚的,没有实现(记住,您仍然可以定义一个实现,但必须显式调用它),并且没有数据成员。非常类似于Java中的“接口”,或者(从我所听到的)

    若要在C++中使用多态性,则不能使用构造函数,必须使用(public)继承。

    因此,如果类栏从可打印和可序列化继承(公开),我可以将对象视为可打印对象、可序列化对象或栏对象(使用指针或引用)。

    有了作文,你就不能这么做。

        10
  •  0
  •   clemahieu    15 年前

    如果您想看到多继承的漂亮实现,请查看埃菲尔。它们通过特性重命名来解决菱形问题,远比范围解析简单,甚至支持直接重复继承,例如:

    A继承B,B,B

    当需要使用这种类型的继承时。

    他们的内核库是开放源码的,如果您想查看示例,可以广泛使用多重继承。

    http://sourceforge.net/projects/eiffelstudio/files/