3

仮想コンストラクタがない場合、なぜ仮想デストラクタがあるのでしょうか。コンストラクターも仮想化できますか?

4

3 に答える 3

26
  • 仮想コンストラクターには意味がありません。作成される型を正確に宣言し、コンパイル時によく知られています。コンパイラは必要ありません[動的ディスパッチはオブジェクトの作成後にのみ作成された情報に基づいているため、実際には必要ありません]。したがって、仮想コンストラクターはありません
  • 仮想デストラクタは、メモリリークを防ぎ、システムを監視するために重要です。A* a = new B;[Bから継承A]があり、後でdelete a;-コンパイラが[一般的な場合]であることを知る方法aがなく、仮想でない場合はのデストラクタBを呼び出すと仮定しますA。メモリリークが発生する可能性があります。または他の障害。
  • 仮想デストラクタの使用-オブジェクトが破棄されているためB、のデストラクタが呼び出されるBようにします。
于 2012-03-29T10:59:22.827 に答える
2

仮想デストラクタが必要なのは、破壊時に、処理しているタイプが常にわからないためです。

Base *make_me_an_object()
{
    if (the_moon_is_full())
        return new Derived();
    else
        return new Base();
}

int main()
{
    Base *p = make_me_an_object();
    delete p;
}

上記deleteのプログラムのは、それがオブジェクトを指しているのかオブジェクトを指しているのmainかを知りませんが、デストラクタが(あるべき姿で)ある場合は、vtableを使用して適切なデストラクタを見つけることができます。pBaseDerivedBasevirtualdelete*p

対照的に、構築時には、作成しているオブジェクトの種類を常に把握しています。(そうでない場合は、ファクトリまたは「仮想コンストラクタ」を作成して、それを認識できます。)

于 2012-03-29T11:00:33.467 に答える
0
#include<iostream>
using namespace std;
class base {
   protected:
    int a;
};
class derived : public base {

};
int main() {
    base * pointer_of_base = new derived;
    delete pointer_of_base; // this will delete the base calss not the derived

}

コンストラクターは、クラスのオブジェクトを作成するときに1回呼び出されるため、基本クラスを継承する場合、コンストラクターは1回だけ呼び出されるため、仮想である必要はありません。

ただし、基本クラスのポインタから派生クラスにアクセスする場合、派生クラスのオブジェクトを削除する場合は、基本クラスのポインタで削除しますが、delete(pointer_of_base)は基本クラスのデストラクタを呼び出しますが、実際にはモットーは、派生クラスを削除することです。したがって、デストラクタは本質的に仮想である必要があります。

于 2017-04-29T06:59:22.197 に答える