私はなぜクラスに負傷します std::future
および std::promise
はfinal
指定子でマークされていません。 destructor はnotvirtualなので、final
が追加されなかったのはなぜですか?理論的根拠は何でしたか?
[微分]/4 に従って:
C++標準ライブラリで指定されているすべての型は、特に指定がない限り、非最終型である必要があります。
そしてstd::future
またはstd::promise
は除外されません。
そしてコメントで述べたように、この問題は以前に議論されました。 ライブラリの実装者は、非ポリモーフィックコンポーネントにfinalを追加する自由がありますか? 。
この問題の解決策は、結論としては欠陥とは見なされなかったことです。
ライブラリがキーワード
final
を仕様で使用しない限り、ユーザーはそのようなクラスから派生する自由を明らかに持っているので、同様に明確にライブラリベンダーはfinal
オーバーライドまたはクラス属性を追加します。
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
などの異なる語彙型を使用することをお勧めします。
クラスに仮想関数がない場合でも、基本クラスとしての資格はありません。私の意見では、基本クラスにvirtual
関数を追加することは、基本クラスを多態的なものにする特別ケースの一種です。多くのプログラマは不注意にvirtual
を関数、特にクラスのデストラクタに配置します(そして "仮想デストラクタが必要である"とコメントします)。 。
たとえば、ATLは継承に大きく依存していますが、仮想関数はありません。 (基本)クラスは非ポリモーフィックです。 C++/STLクラスのほとんど(すべてではないにしても)は非多態性です。
「継承よりも包含/構成を優先する」という規則を破り、非論理的な形式のクラスから派生する場合があります(lubgrが提供する1つの例)。しかし、これは実行可能であり、有効です。クラスを含むのではなく、非多態的なクラスから継承する方が適切な場合があります。
テンプレート/テンプレートメタクラスは、仮想関数が関与しない継承に依存しています。属性継承は1つの例であり、クラスはさまざまなクラスから継承し(多重継承)、属性を継承します。
非常に単純な例の1つは、クラスnon_copyable
、copy-constructor/assignment-operatorなどをprivate/protectedとして配置します。そして、他のクラスにそれを継承させます。このようにして、「派生」クラスは、基本クラスのnon-copyable「機能/属性」を継承します。