摘要 类 与模板 - 良好实践
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(不同语言的界面)(一点点也许更好的表现?)
我的问题是:
哪种方法更好?
当有选择时,我们应该在库中以模板方式还是抽象方式实现事物?
标准是否有理由不定义某些标准 "Interfaces",例如 std::container 或 std::factory(仅示例)?
这似乎是一个基于意见的问题。强迫客户履行义务的最好方法是让他签合同,合同就是一个接口。
其实你的问题不止一个,下面我们一一解答:
Which approach is better?
总的来说两者都不是更好。每个人都有长处和短处。但是您确实得出了一个有趣的观点:在更抽象的层面上,这两者几乎相同。
When having the choice should we implement things in a template way or abstract way in a library?
使用模板您可以获得:
总的来说,执行速度更快。它可以 多 更快,因为可以进行大量内联,然后进行优化。 OTOH,具有高级去虚拟化 compiler/linker 和不能太多的功能 inlined/optimized,您可能会获得几乎相同的速度。
编译时间较慢。它可能 很多 慢,特别是如果你走 "fancy template-meta-programming" 方式。
更严重的编译器错误。它们可能 更 更糟,尤其是如果您选择 "fancy template-meta-programming" 方式。当C++获得对概念的支持时,应该可以避免这种情况。
如果你仔细设计它,提高了类型安全性。 OTOH,如果你不小心,你最终会遇到比 Smalltalk 更糟糕的鸭子打字。在这方面,概念也是一种可以提供帮助的工具。
使用虚函数/接口,你得到:
- 去耦合设计,如果您小心的话,一个文件的更改不需要重新编译其他文件,并且编译时间可以更快。
- 运行-时间多态性,这意味着您可以动态加载代码(这并不像听起来那么容易,但是,这是可能的)
- 有 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" 几乎是不可能的。
假设我有某种 class,它代表算法,并且该算法需要数据中的某些特殊内容(例如,某些成员函数)。
例如我们可以这样做:
<<interface>>
+------------------------+ +------------+
| Algorithm | <<uses>> | Data |
+------------------------+-------------->+------------+
| + doJob(inData : Data) | | +getPixel()|
+------------------------+ +------------+
并且我们可以强制 Algorithm 的用户每次想使用 class 算法时都从 Data 继承。我们也可以做一个模板:
template<typename T>
doJob(T&& inputData){
//implementation
}
(函数没有 class 以简化事情)
并且我们强制我们的客户创建 classes,这些方法具有专有名称的方法,但我们不让他实现我们的抽象 class(不同语言的界面)(一点点也许更好的表现?)
我的问题是:
哪种方法更好?
当有选择时,我们应该在库中以模板方式还是抽象方式实现事物?
标准是否有理由不定义某些标准 "Interfaces",例如 std::container 或 std::factory(仅示例)?
这似乎是一个基于意见的问题。强迫客户履行义务的最好方法是让他签合同,合同就是一个接口。
其实你的问题不止一个,下面我们一一解答:
Which approach is better?
总的来说两者都不是更好。每个人都有长处和短处。但是您确实得出了一个有趣的观点:在更抽象的层面上,这两者几乎相同。
When having the choice should we implement things in a template way or abstract way in a library?
使用模板您可以获得:
总的来说,执行速度更快。它可以 多 更快,因为可以进行大量内联,然后进行优化。 OTOH,具有高级去虚拟化 compiler/linker 和不能太多的功能 inlined/optimized,您可能会获得几乎相同的速度。
编译时间较慢。它可能 很多 慢,特别是如果你走 "fancy template-meta-programming" 方式。
更严重的编译器错误。它们可能 更 更糟,尤其是如果您选择 "fancy template-meta-programming" 方式。当C++获得对概念的支持时,应该可以避免这种情况。
如果你仔细设计它,提高了类型安全性。 OTOH,如果你不小心,你最终会遇到比 Smalltalk 更糟糕的鸭子打字。在这方面,概念也是一种可以提供帮助的工具。
使用虚函数/接口,你得到:
- 去耦合设计,如果您小心的话,一个文件的更改不需要重新编译其他文件,并且编译时间可以更快。
- 运行-时间多态性,这意味着您可以动态加载代码(这并不像听起来那么容易,但是,这是可能的)
- 有 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" 几乎是不可能的。