为什么std :: future和std :: promise不是最终的?

时间:2019-04-17 10:39:03

标签: c++ c++11 c++14 language-lawyer

我讨厌为什么类std::futurestd::promise没有用final标记符标记。 destructor不是虚拟,为什么没有添加final?基本原理是什么?

3 个答案:

答案 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::promisestd::future这样的不同词汇类型

答案 1 :(得分:16)

根据[derivation]/4

  

在C ++标准库中指定的所有类型均应为非最终类型,除非另有说明。

不排除std::futurestd::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;并让其他类从中继承。这样,“派生”类将继承基类的不可复制“功能/属性”。