4

必要がない場合でも、常にクラスに仮想デストラクタをマークします。わずかなパフォーマンス ヒット以外に、仮想デストラクタが必要ないときに仮想デストラクタを使用すると、メモリ エラーや何かひどいことが発生する可能性があります。

ありがとう

4

3 に答える 3

16

すべてのクラスを拡張可能にすることは根本的な欠陥です。ほとんどのクラスは継承元に適していません。事前に拡張用のクラスを設計しないと、継承を容易にする意味がありません

これは、クラスが意味のある継承可能であるというヒントとしてこれを受け取る APIのユーザーを誤解させるだけです。実際には、これはまれなケースであり、何のメリットももたらさないか、最悪の場合コードが壊れます。

クラスを継承可能にすると、残りの人生はそれで解決します。そのインターフェイスを変更することはできず、その(暗黙の!) セマンティクスを決して壊してはなりません。基本的に、クラスはもはやあなたのものではありません。

一方、継承はとにかく過大評価されています。パブリック インターフェイス (純粋な仮想クラス) での使用とは別に、通常は継承よりも構成を優先する必要があります。

仮想デストラクタが望ましくないもう 1 つのより基本的なケースは、コードが動作するためにPODを必要とする場合です。たとえば、 で使用するunion場合、C コードとインターフェイスする場合、または POD 固有の最適化を実行する場合 (POD のみが blittable であり、つまり、非常に効率的にコピーできます)。[アンディへの​​帽子のヒント]

パフォーマンスのオーバーヘッドについて: 多数の小さなオブジェクトが作成されたり、オブジェクトがタイトなループで作成されたりする状況があります。そのような場合、仮想デストラクタのパフォーマンス オーバーヘッドは重大な間違いになる可能性があります。

また、仮想関数テーブルを持つクラスは、持たないクラスよりも大きくなり、パフォーマンスに不必要な影響を与える可能性があります。

全体として、デストラクタを仮想化する説得力のある理由はなく、そうしない説得力のある理由もいくつかあります。

于 2012-04-23T23:09:02.050 に答える
2

クラスからの継承を計画していない場合 (またはクラスが継承されることを意図していない場合) は、仮想として宣言しても意味がありません。
一方、このクラスにポリモーフィックにアクセスする場合は、はい、仮想デストラクタを使用すると便利です。

しかし、あなたの質問に正確に答えるために、「ひどいメモリエラー」が発生することはなく、常に仮想とマークしても実際に害はありません。

しかし、常に仮想デストラクタを使用する理由はありません。それはあなた次第です。

また、ハーブによるこの投稿は、問題にいくつかの光をもたらします.

于 2012-04-23T23:10:15.083 に答える
0

いいえ、知る限り。仮想デストラクタは、非仮想デストラクタとまったく同じように動作する (つまり、仮想呼び出しと直接呼び出しが同じ関数を呼び出す) か、未定義の動作になります。したがって、非仮想デストラクタを仮想デストラクタに変更することによって「ひどいことをする」ことはできません。

ただし、コードの他の部分によって引き起こされたエラーを明らかにする可能性があります。オブジェクトの仮想テーブル ポインタを誤って上書きした場合。

于 2012-04-23T23:12:45.753 に答える