【问题标题】:Template or Inheritance [closed]模板或继承[关闭]
【发布时间】:2015-07-24 20:28:01
【问题描述】:

你更喜欢哪一个:

template <class STRATEGY>
class A
{
  STRATEGY *m_pMyStrategy; // User has to create new strategy class
// class A needs to use traits 
// or some other means to decide if strategy meets the requirements

};

class A
{
  IBaseStrategy *m_pMyStrategy; // User inherits IBaseStrategy class
};

为什么 std::vector 为分配器选择第一个?

【问题讨论】:

  • 整个 std 集合都专注于模板而不是继承。
  • 查找运行时和编译时多态性。
  • 我可能不会问“你更喜欢哪个?”在这里提出问题,因为如果两者都完成相同的任务,则由程序员来解释一个实现是否比另一种更可取。
  • 两个sn-ps都非常糟糕。
  • 我认为标准委员会承认std::vector 处理分配器的方式是错误的设计。

标签: c++ templates inheritance stl


【解决方案1】:

我们大多数人可能更喜欢(可能会更喜欢,当它可用时)是使用某种概念,这样我们就可以吃蛋糕了(可以这么说):将STRATEGY 作为模板参数,还要指定STRATEGY需要满足的要求。

您的第二个(基于继承的)版本导致了一个根本问题:虽然它可以很容易地从策略类中指定客户端类所需的接口,但它要求策略类的作者知道策略类的名称编写策略类时的策略基类。

换句话说,策略类提供正确的接口是不够的——它需要从正确的基类继承来通知编译器它提供了那个特定的接口。

这在大型项目中变得特别笨拙——您需要大量的跨项目协调来确保人们需要的所有接口都提前设计和了解,因此每个要提供策略课程的人当他们定义自己的类时,知道使用什么作为基类。

概念降低了必要的通信级别,因为不需要从指定的基类继承策略来表明它实现了特定的接口,客户端类可以直接指定它需要的接口,以及任何符合可以使用这些要求。如果代码不同部分中的两个不同的客户端类都想使用相似的策略,他们不必首先协调(例如)就他们将接受的策略的基类名称达成一致——相反,每个只指定它需要的接口,并且任何满足该接口要求的类都可以用于该角色(即使它的作者甚至从未听说过他们为接口选择的名称,更不用说将其用作基类)。

目前,模仿具有特征组合的概念和static_assert 之类的东西可能是我们能做的最好的事情。代码通常丑陋而笨拙,但至少它的基本原理是正确的——特别是它把责任放在了正确的地方。

由于“在正确的地方的责任”部分可能不清楚,我的意思是编写策略类的人只需要负责提供正确的接口,而不是基本上猜对了客户端类可能会选择为他们定义的基类指定什么名称(例如),以指定他们想要的接口。这也意味着客户端和服务器端(或任何您喜欢的名称)都更关心功能,而不是发明名称,并让其他人正确猜测名称。

【讨论】:

    猜你喜欢
    • 2014-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-22
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    • 2013-12-13
    相关资源
    最近更新 更多