4

这是由于过于宽泛而搁置的问题的较窄版本。

Modern C++ Design的第 6-7 页上,Andrei Alexandrescu 列出了在构建灵活设计方面多重继承弱于模板的三种方式。特别是,他指出多重继承提供的机制很差(根据对上下文的理解,方括号中的文本和格式是我的):

在这样的设置中[即多重继承],[构建一个灵活的,]用户将通过继承一些类和两个类SmartPtr来构建一个多线程、引用计数的智能指针类:和。任何有经验的类设计师都知道,这种幼稚的设计是行不通的。BaseSmartPtrMultiThreadedRefCounted

...

  1. 力学。没有样板代码可以以受控方式组装继承的组件。唯一结合 BaseSmartPtr、MultiThreaded 和 RefCounted 的工具是一种称为多重继承的语言机制。该语言在组合基类时应用了简单的叠加,并建立了一组访问其成员的简单规则。除了最简单的情况外,这是不可接受的。大多数时候,您需要仔细协调继承类的工作以获得所需的行为。

使用多重继承时,可以通过编写调用多个基类的成员函数的成员函数来实现一些非常灵活的编排。那么,多重继承中缺少并存在于模板中的编排是什么?

请注意,与模板相比,并不是多重继承的所有缺点都可以作为答案,而只是上面引用中 Andei 所谓的机制的缺点。特别是,请确保您不是在谈论Andrei 列出的其他两个多重继承弱点之一:

  1. 类型信息。基类没有足够的类型信息来执行它们的任务。例如,假设您尝试通过从 DeepCopy 基类派生来为您的智能指针类实现深度复制。但是 DeepCopy 会有什么接口呢?它必须创建它还不知道的类型的对象。

  2. 状态操纵。使用基类实现的各种行为方面必须操纵相同的状态。这意味着他们必须使用虚拟继承来继承持有状态的基类。这使设计复杂化并使其更加僵化,因为前提是用户类继承库类,反之亦然。

4

1 回答 1

0

我认为 Alexandrescu 在“力学”段落中所指的内容将在本章的其余部分进行阐述。他指的是基于策略的类设计比基于继承的类设计要灵活得多,特别是关于可以实现和组合策略的各种方式——这与通过多重继承允许的单一实现和组合相比。

例如,在讨论Creator策略时,他指出该策略只需要一个 Create() 方法,该方法返回一个指向正在创建的类的指针,但没有指定它是虚拟的还是非静态的。他还展示了创建每个策略的几种方法:一个简单的策略类,例如(从第 1.5 节开始,跳过 MallocCreator 和 PrototypeCreator 策略)

template<class T>
struct OpNewCreator
{
  static T* Create()
  {
    return new T;
  }
}; 

...

>     //Library code
>     template <class CreationPolicy>
>     class WidgetManager:public CreationPolicy
>     {
>     ...
>     };

...

// Application Code
typedef WidgetManager<OpNewCreator<Widget> > MyWidgetMgr;

或者它可以使用模板模板参数(第 1.5.1 节)作为

//Library Code
template <template <class> class Creation Policy>
class WidgetManager : public CreationPolicy <Widget>
{
...
}

// Application Code
typedef WidgetManager<OpNewCreator> MyWidgetMgr

或(第 1.5.2 节) - 实现为模板成员函数:

struct OpNewCreator
{
  template <class T>
  static T* Create()
  {
    return new T;
  }

}

这些是在基于模板的策略类解决方案中可用但在多重继承解决方案中不可用的灵活机制的示例。这些特定的例子可能并不那么令人兴奋,可能是因为出于教学原因,它们必须简短而简单。

于 2015-10-07T09:32:47.040 回答