我讨厌为什么类std::future
和std::promise
没有用final
标记符标记。 destructor不是虚拟,为什么没有添加final
?基本原理是什么?
答案 0 :(得分:19)
用std::vector
看一下这个人为的(毫无意义的)示例:
template <class T>
struct Example : private std::vector<T> {
void doStuff(const T& t) { this->push_back(t); }
T retrieveStuff() { return this->operator[](0); }
};
Example<int> e;
e.doStuff(42);
std::cout << e.retrieveStuff() << "\n";
这行得通,因为std::vector::~vector
不是virtual
,所以您无法进入UB,因为您不能通过基类指针删除对象(那里需要public
继承) )。
这里的继承只是实现细节。不推荐这样做,但是人们可能这样做了。一旦决定不通过制作std::vector
或其他容器类型final
来破坏现有代码,就应该坚持使用std::promise
或std::future
这样的不同词汇类型
答案 1 :(得分:16)
在C ++标准库中指定的所有类型均应为非最终类型,除非另有说明。
不排除std::future
或std::promise
。
正如评论中提到的那样,此问题之前已经讨论过。 Do library implementers have the freedom to add final to non-polymorphic components?。
此问题的解决方案是,该结论不被认为是缺陷:
除非图书馆在规范中使用关键字
final
,否则用户显然拥有从此类中派生的自由,并且同样清楚地,图书馆供应商没有添加{{ 1}}覆盖程序或类属性。
答案 2 :(得分:0)
一个类中不存在任何虚函数并不会使它不符合基类的条件。我认为,将virtual
函数添加到基类是将基类设为多态的特殊情况。许多程序员粗心地将virtual
放在函数中,尤其是在类的析构函数上(并指出“虚拟析构函数是必需的” )。
ATL严重依赖于继承,但没有任何虚函数。 (基本)类是非多态的。大多数(如果不是全部)C ++ / STL类都是非多态的。
一个人可能会违反“优先选择包含/组成而不是继承”的规则,并以不合逻辑的形式从类中派生(lubgr给出了一个示例);但这是可行且有效的。有时,从非多态类继承而不是包含类更合适。
Template / Template-meta类依赖于继承,其中不涉及任何虚函数。属性继承就是一个示例,其中一个类将从多个不同的类继承(多重继承),并继承属性。
一个非常简单的示例将是制作一个类non_copyable
,将copy-constructor / assignment-operator等设置为private / protected;并让其他类从中继承。这样,“派生”类将继承基类的不可复制“功能/属性”。