仮想コンストラクタを持っていないと、なぜ仮想デストラクタがあるのですか?コンストラクタも仮想である可能性がありますか?いいえ仮想コンストラクタではなく仮想デストラクタ
2
A
答えて
16
- は、仮想コンストラクタにはポイントがありません - あなたは タイプが作成された正確に何を宣言し、それがうまくコンパイル時に知られています。コンパイラ は、動的ディスパッチは、オブジェクトが作成された後にのみ作成される情報に基づいて に基づいているため、[実際にはできません]。 したがって仮想コンストラクタはありません。
- 仮想デストラクタはメモリリークを防ぐために重要で、 はシステムを監視します。あなたは
A* a = new B;
を持っていると仮定しますが、後でdelete a;
[B
がA
から を継承]、および - コンパイラが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
かどうかわからない:
2
仮想デストラクタが原因で破壊時に必要とされ、あなたは常にあなたが扱っているタイプか分かりませんBase
またはDerived
オブジェクトを指していますが、Base
デストラクタがvirtual
の場合、delete
は*p
のvtableを使用して、正しいデストラクタを見つけることができます。
これに対して、建設時には、作成しているオブジェクトの種類が常にわかります。 (そして場合は、あなたは、あなたは知っているん工場や「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)は基底のデストラクタを呼び出します実際のモットーは派生クラスを削除することです。したがって、デストラクタは本質的に仮想的である必要があります。
可能な複製[なぜC++で仮想コンストラクタを持たないのですか?](http://stackoverflow.com/questions/733360/why-do-we-not-have-a-virtual-constructor-in- c) –
@ TomaszNurkiewicz:私は疑問がむしろ、なぜC++で仮想デストラクタを使用するのでしょうか? –