2012-03-29 14 views
2

仮想コンストラクタを持っていないと、なぜ仮想デストラクタがあるのですか?コンストラクタも仮想である可能性がありますか?いいえ仮想コンストラクタではなく仮想デストラクタ

+0

可能な複製[なぜC++で仮想コンストラクタを持たないのですか?](http://stackoverflow.com/questions/733360/why-do-we-not-have-a-virtual-constructor-in- c) –

+1

@ TomaszNurkiewicz:私は疑問がむしろ、なぜC++で仮想デストラクタを使用するのでしょうか? –

答えて

16
  • は、仮想コンストラクタにはポイントがありません - あなたは タイプが作成された正確に何を宣言し、それがうまくコンパイル時に知られています。コンパイラ は、動的ディスパッチは、オブジェクトが作成された後にのみ作成される情報に基づいて に基づいているため、[実際にはできません]。 したがって仮想コンストラクタはありません。
  • 仮想デストラクタはメモリリークを防ぐために重要で、 はシステムを監視します。あなたはA* a = new B;を持っていると仮定しますが、後でdelete a; [BAから を継承]、および - コンパイラがaを知る 方法がありません[一般的な場合] Bあり、かつA年代 デストラクタを呼び出します - それがなかった場合仮想で、メモリリーク、 またはその他の障害が発生する可能性があります。
  • 仮想デストラクタを使用する - あなたはBオブジェクトがを破壊されているのでBのデストラクタは、呼び出さ であることを確認

    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はそのpかどうかわからない:

+0

私は最初の点を理解していませんでした。あなたはそれを精巧にできますか? – devsda

+1

@jhamb:コンストラクタを呼び出すと、それは 'new MyClass;'のようなものです。作成されたオブジェクトの* dynamic型*と* static型*は、実際の具体的なオブジェクトとまったく同じです。 – amit

2

仮想デストラクタが原因で破壊時に必要とされ、あなたは常にあなたが扱っているタイプか分かりませんBaseまたはDerivedオブジェクトを指していますが、Baseデストラクタがvirtualの場合、delete*pvtableを使用して、正しいデストラクタを見つけることができます。

これに対して、建設時には、作成しているオブジェクトの種類が常にわかります。 (そして場合は、あなたは、あなたは知っているん工場や「virtual constructor」を作成することができません。)私たちは私たちが受け継ぐので、クラスのオブジェクトを作成するときに

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)は基底のデストラクタを呼び出します実際のモットーは派生クラスを削除することです。したがって、デストラクタは本質的に仮想的である必要があります。