STL コンテナに仮想デストラクタがない理由を知っている人はいますか?
私が知る限り、唯一の利点は次のとおりです。
- インスタンスのサイズを (仮想メソッド テーブルへの) 1 つのポインターだけ減らします。
- 破壊と構築が少し速くなります。
欠点は、コンテナを通常の方法でサブクラス化するのは安全ではないことです。
編集: おそらく私の質問は、「継承を許可するように設計された STL コンテナーではなかったのはなぜですか?」と言い換えることができます。
それらは継承をサポートしていないため、STL 機能と少数の追加機能 (マップのデフォルト値を持つ特殊なコンストラクターまたは新しいアクセサーなど) を必要とする新しいコンテナーが必要な場合、次の選択肢に行き詰まります。または何でも):
- コンポジションとインターフェイスのレプリケーション: STL コンテナーをプライベート メンバーとして所有し、STL メソッドごとに 1 つのパススルー インライン メソッドを持つ新しいテンプレートまたはクラスを作成します。これは継承と同じくらいパフォーマンスが高く、仮想メソッド テーブルのコストを回避できます (重要な場合)。残念ながら、STL コンテナーにはかなり幅広いインターフェイスがあるため、一見簡単に実行できるはずのコード行が多数必要になります。
- Just make functions : メンバー関数を追加する代わりに、ファイル スコープの関数を使用します。いくつかの点でこれは良い方法かもしれませんが、カプセル化の利点は失われます。
- パブリック STL アクセスによる構成: STL コンテナーの所有者に、ユーザーが STL コンテナー自体にアクセスできるようにします (おそらくアクセサーによって保護されます)。これにより、ライブラリ作成者のコーディングは最小限で済みますが、ユーザーにとってはあまり便利ではありません。コンポジションの大きなセールス ポイントの 1 つは、コード内の結合を減らすことですが、このソリューションでは、STL コンテナーと所有者コンテナーが完全に結合されます (所有者が真の STL コンテナーを返すため)。
- コンパイル時のポリモーフィズム: 書くのがやや難しい場合があり、コードの体操が必要で、すべての状況に適しているわけではありません。
副次的な質問として、非仮想デストラクタを使用してサブクラス化する標準安全な方法はありますか (新しいメソッドを追加したいだけで、メソッドをオーバーライドしたくないと仮定しましょう)。私の印象では、非仮想クラスを定義するコードを変更する権限がない場合、これを行う一般的で安全な方法はありません。
編集2:
@docが指摘しているように、C++ 11 の洗練されusing
た宣言により、構成のコストがいくらか削減されます。