web-dev-qa-db-ja.com

std :: futureとstd :: promiseがfinalではないのはなぜですか?

私はなぜクラスに負傷します std::future および std::promisefinal指定子でマークされていません。 destructornotvirtualなので、finalが追加されなかったのはなぜですか?理論的根拠は何でしたか?

14
Sonic78

[微分]/4 に従って:

C++標準ライブラリで指定されているすべての型は、特に指定がない限り、非最終型である必要があります。

そしてstd::futureまたはstd::promiseは除外されません。

そしてコメントで述べたように、この問題は以前に議論されました。 ライブラリの実装者は、非ポリモーフィックコンポーネントにfinalを追加する自由がありますか?

この問題の解決策は、結論としては欠陥とは見なされなかったことです。

ライブラリがキーワードfinalを仕様で使用しない限り、ユーザーはそのようなクラスから派生する自由を明らかに持っているので、同様に明確にライブラリベンダーはfinalオーバーライドまたはクラス属性を追加します。

16
P.W

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::~vectorvirtualではないためにUBに入ることができません。これは、基本クラスポインターを通じてオブジェクトを削除できないためです(public継承が必要です)。

ここでの継承は、単なる実装の詳細です。推奨されるプラクティスではありませんが、人々はおそらくこれを実行しました。 std::vectorまたは他のコンテナー型をfinalにすることで既存のコードを壊さないことが決定したら、std::promisestd::futureなどの異なる語彙型を使用することをお勧めします。

19
lubgr

クラスに仮想関数がない場合でも、基本クラスとしての資格はありません。私の意見では、基本クラスにvirtual関数を追加することは、基本クラスを多態的なものにする特別ケースの一種です。多くのプログラマは不注意にvirtualを関数、特にクラスのデストラクタに配置します(そして "仮想デストラクタが必要である"とコメントします)。 。

たとえば、ATLは継承に大きく依存していますが、仮想関数はありません。 (基本)クラスは非ポリモーフィックです。 C++/STLクラスのほとんど(すべてではないにしても)は非多態性です。

「継承よりも包含/構成を優先する」という規則を破り、非論理的な形式のクラスから派生する場合があります(lubgrが提供する1つの例)。しかし、これは実行可能であり、有効です。クラスを含むのではなく、非多態的なクラスから継承する方が適切な場合があります。

テンプレート/テンプレートメタクラスは、仮想関数が関与しない継承に依存しています。属性継承は1つの例であり、クラスはさまざまなクラスから継承し(多重継承)、属性を継承します。

非常に単純な例の1つは、クラスnon_copyable、copy-constructor/assignment-operatorなどをprivate/protectedとして配置します。そして、他のクラスにそれを継承させます。このようにして、「派生」クラスは、基本クラスのnon-copyable「機能/属性」を継承します。

0
Ajay