2011-07-23 18 views
4

ポインタを持つ構造体をそのメンバの1つとして持つクラスがあります。ポインタの構造を持つクラスにはデストラクタが必要です

struct group { 
    void *v1, 
    void *v2; 
}; 


class A { 
    A (group& handle) 
    : m_handle(handle) 
private : 
    group m_handle; 
}; 

は、私は何のデストラクタがAで定義されていないとき、私は、オブジェクトAは、デストラクタスコープの外に出たとき、ということを学びました(たとえば、メモリリークなど)すべての問題が表示されていないクラスAに何のポインタメンバーはありませんAのメンバークラスが呼び出されると、それらのデストラクタが呼び出されます。では、上記のm_handleのようなメンバ構造体はどうなるのですか?デストラクタに似た何かがあり、オブジェクトAがスコープ外に出たときに構造体グループの2つのvoidポインタが削除されていますか?

+0

"削除された"ポインタに関する不明な言葉があります。ポインタそのものはうまく削除されますが、他の人が指摘しているように、ポインタが指すメモリは削除されません。 –

答えて

4

はい、v1とv2は、プログラムの他の部分で割り当てが解除されていないと、リークする可能性があります。したがって、Aのデストラクタでは、v1とv2を削除することができます(適切な場合)。または、デストラクタをグループに追加することができます(C++では、structはデフォルトの可視性を除いてクラスのようです)プライベートではなく)、削除してください。もちろん、これは妥当性(おそらく、v1とv2を割り当てて所有している他のもの)によって決まります。

+0

ありがとうございます。v1とv2は別のモジュールで割り当てられています。構造体を削除するAPIがあります.Aのデストラクタ内でdeleteGroup APIを呼び出す必要があります。これは私の考えでもあります。 'Aのデストラクタが定義されておらず、浄化のメモリリークが見当たりません。 – cppcoder

+0

void *は、おそらくメモリのチャンクではなくC++オブジェクトへのポインタであると仮定して、削除しないでください。それらがメモリのチャンクへのポインタである場合、なぜあなたはuint8_tの代わりにvoid *を使用していますか、より説明的なものがありますか? void *を削除する際に観察可能な問題は、デストラクタが呼び出されないことです。したがって、クラスのインスタンスであれば、そのクラスのAPIは違反されています。標準の呼び出しでは、void *のdeleteは未定義の動作です。 –

+0

@Dan - struct group内のv2は、別のグループを指しているか、float、stringまたはintのいずれかを含む別の共用体である可能性があります。この場合v2を削除してもよろしいですか? – cppcoder

0

groupがこれらのポインタを所有している場合にはそれらを解放するデストラクタが必要です(どのように割り当てたかによって異なります)。また、のポインタはnewまたはmallocに割り当てられていますか? void*が必要ですか?特定のタイプではありませんか?

あなたが持っているように、タイプgroupのオブジェクトが破壊されると、それらの2つのポインタには何も特別なことは起こらず、解放されません。理想的には、これらのポインタの「所有権」という概念を持つべきです。割り当てを行うクラスは通常、割り当てを解除すべきクラスです。

+2

'void *'上の 'delete'はUBです。 –

+0

@honk:良い点、私はより正確に編集しました:-)。 –

0

スコープ外に出ると、クラス内の構造がクリーンアップされます。しかし、メモリv1とv2のポイントは自動的にクリーンアップされません。

0

本質的には、クラスも構造体も、デフォルトのコンストラクタ/デストラクタはありません。コンパイラはデフォルトのデストラクタを実行する方法を理解できません。したがって、管理するポインタメンバーがある場合は、常に独自のコンストラクタとデストラクタを実装する必要があります。ポインタを所有していない場合は、それを気にする必要はありませんが、コンストラクタを持つのは良い習慣です。

関連する問題