摘要 类 与模板 - 良好实践

Abstract classes vs. templates - good practices

假设我有某种 class,它代表算法,并且该算法需要数据中的某些特殊内容(例如,某些成员函数)。

例如我们可以这样做:

                                          <<interface>>
+------------------------+               +------------+
|       Algorithm        |    <<uses>>   |    Data    |
+------------------------+-------------->+------------+
| + doJob(inData : Data) |               | +getPixel()|
+------------------------+               +------------+

并且我们可以强制 Algorithm 的用户每次想使用 class 算法时都从 Data 继承。我们也可以做一个模板:

template<typename T>
doJob(T&& inputData){
   //implementation
}

(函数没有 class 以简化事情)

并且我们强制我们的客户创建 classes,这些方法具有专有名称的方法,但我们不让他实现我们的抽象 class(不同语言的界面)(一点点也许更好的表现?)

我的问题是:

哪种方法更好?

这似乎是一个基于意见的问题。强迫客户履行义务的最好方法是让他签合同,合同就是一个接口。

其实你的问题不止一个,下面我们一一解答:

Which approach is better?

总的来说两者都不是更好。每个人都有长处和短处。但是您确实得出了一个有趣的观点:在更抽象的层面上,这两者几乎相同。

When having the choice should we implement things in a template way or abstract way in a library?

使用模板您可以获得:

  1. 总的来说,执行速度更快。它可以 更快,因为可以进行大量内联,然后进行优化。 OTOH,具有高级去虚拟化 compiler/linker 和不能太多的功能 inlined/optimized,您可能会获得几乎相同的速度。

  2. 编译时间较慢。它可能 很多 慢,特别是如果你走 "fancy template-meta-programming" 方式。

  3. 更严重的编译器错误。它们可能 更糟,尤其是如果您选择 "fancy template-meta-programming" 方式。当C++获得对概念的支持时,应该可以避免这种情况。

  4. 如果你仔细设计它,提高了类型安全性。 OTOH,如果你不小心,你最终会遇到比 Smalltalk 更糟糕的鸭子打字。在这方面,概念也是一种可以提供帮助的工具。

使用虚函数/接口,你得到:

  1. 去耦合设计,如果您小心的话,一个文件的更改不需要重新编译其他文件,并且编译时间可以更快。
  2. 运行-时间多态性,这意味着您可以动态加载代码(这并不像听起来那么容易,但是,这是可能的)
  3. 有 OO 经验的人看起来更熟悉的东西。

Is there a reason for standard not to define some standard "Interfaces" like std::container or std::factory (just examples)?

我想可以找到很多 "low-level" 原因,但根本原因是性能。也就是说,STL 被设计为 "as fast as can be",现在放置一些(有用的)接口 "on top if it" 几乎是不可能的。