仮想デストラクタを持つ基本クラスがある場合。仮想デストラクタも宣言する派生クラスがありますか?
class base {
public:
virtual ~base () {}
};
class derived : base {
public:
virtual ~derived () {} // 1)
~derived () {} // 2)
};
具体的な質問:
final
を使用して、派生クラスでオーバーライドされないようにすることができますが、仮想になることを防ぐことはできません。virtual
キーワードを再度使用します。関数が仮想であることを理解するために、人々は継承階層をずっと上に行く必要はありません。さらに、独自のコピーまたは移動コンストラクターを宣言せずにクラスがコピー可能または移動可能である場合、(default
として定義した場合でも)あらゆる種類のデストラクタを宣言すると、コピーおよびコンストラクターの宣言が強制されますコンパイラがそれらを挿入しないため、必要に応じて演算子を割り当てます。項目3の小さなポイントとして、コメントで指摘されているように、デストラクタが宣言されていない場合、コンパイラはデフォルトの(まだ仮想的な)コンパイラを生成します。そして、そのデフォルトはインライン関数です。
インライン関数は、プログラムの他の部分の変更にプログラムをさらす可能性が高く、共有ライブラリのバイナリ互換性を扱いにくいものにします。また、結合の増加により、特定の種類の変更に直面して多くの再コンパイルが発生する可能性があります。たとえば、仮想デストラクタの実装が本当に必要であると判断した場合、それを呼び出したすべてのコードを再コンパイルする必要があります。クラス本体で宣言してから.cpp
ファイルで空に定義した場合、再コンパイルせずに変更しても問題ありません。
私の個人的な選択は、可能な限りそれを省略することです。私の意見では、それはコードを乱雑にし、コンパイラは空の実装よりもデフォルトの実装でわずかに効率的な処理を実行できる場合があります。しかし、あなたが下にあるかもしれない制約があり、それはそれを悪い選択にします。
仮想メンバー関数は、この関数のオーバーロードを暗黙的に仮想化します。
したがって、1)の仮想は「オプション」であり、仮想である基本クラスデストラクタはすべての子デストラクタも仮想にします。
1 /はい2 /はい、コンパイラーによって生成されます3 /仮想宣言するかどうかの選択は、オーバーライドされた仮想メンバーの規則に従う必要があります-私見、両方の方法で適切な引数があり、1つを選択してそれに従うだけです。
可能な場合は省略しますが、宣言するように促す可能性のあるものが1つあります。コンパイラで生成されたものを使用する場合、暗黙的にインラインになります。インラインメンバー(動的ライブラリなど)を避けたいときがあります。