【问题标题】:Avoiding redundant code in a hierarchy of classes避免类层次结构中的冗余代码
【发布时间】:2014-05-03 21:15:02
【问题描述】:

我有一个特定情况(在 C++ 中),我希望避免在一组类中重复相同的代码,这些类派生自另一组类,而我无法将此代码粘贴到其中。并且以某种方式解决这个问题最终以钻石继承问题告终。下面的例子将解释这种情况:

template <class T>
class A{
    ...
    virtual List<T>* create_list() = 0;   //Factory method
};

template <class T> 
class B: public A{
    ... // Does NOT implement create_list, as 
    //List is an abstract class and is not implemented
    //at this level of abstraction
};

现在,我们有一组派生自上述任一抽象类的类。

class C: public A{};
class D: public B{};
class E: public B{};
... and so on

我们有一个List 的实现,格式为VectorList

所有他们必须通过返回VectorList来实现create_list。他们的实现都是相同的

VectorList* create_list(){
   return new VectorList;
}

我能想到的唯一方法是创建一个类X 实现A 并使所有这些执行多重继承。也就是说,

class X: public A{
    VectorList* create_list(){
      return new VectorList;
    }
};
class C: public A, public X;
class D: public B, public X;

但是,这会产生菱形继承问题,这意味着我必须使用虚拟继承。但我明白这不是一个好的设计。

还有其他选择吗?

【问题讨论】:

  • 您可能想看看CRTP。如果仅仅创建一个通用的中间基类是不够的,那应该可以满足您的需求。
  • 如果所有的类都实现了相同的,那你为什么还需要一个虚函数呢?或者充其量只在需要时覆盖一次。你没有必须将所有虚函数都放在一个抽象的基础上。
  • 我不太明白这个链接。我刚刚经历了你提到的模式。请您在这种情况下详细说明一下吗?
  • @KerrekSB:它们都实现了相同的东西,是的。但我不希望它在 A 或 B 的抽象级别实现。也就是说,我希望 create_list 在该级别未定义。无论谁实现了 A 类和 B 类,都可以随意实现它。碰巧在我选择的实现中,即在 C 和 D 中,我决定以相同的方式实现它们。
  • 我无法从这里的详细程度判断,但您可能在使用继承时组合会更好。

标签: c++ design-patterns inheritance


【解决方案1】:

使用接口和组合:

为 A 类创建一个接口(我们称之为 IA)。 为 A 类创建一个默认实现(我们称之为 implA)

class implA: public IA

为 B 类创建一个接口(我们称之为 IB)

class IB: public IA

为 B 类创建一个默认实现(我们称之为 implB)

class implB: public implA, public IB

在 implA 中实现您的 create_list 方法。 C、D 和 E 应该是:

class C: public implA
class D: public implB
class E: public implB

有关 C++ 接口的更多信息,请参阅:How do you declare an interface in C++?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-14
    • 1970-01-01
    • 2021-04-28
    • 2017-09-16
    • 2023-04-05
    • 1970-01-01
    相关资源
    最近更新 更多