デストラクタで動的に割り当てられたすべてのメモリを解放する必要があります。これは自動的には行われません。
クラスには 2 つのポインターが含まれており、基本的にこれらが何を指しているかを制御することはできません。実際、これらは削除が許可されていないオブジェクトを指している可能性があります。次に例を示します。
struct Foo {};
struct Bar {
Foo* f_;
Foo(Foo* f) : f(f_) {}
};
int main() {
Foo f;
Bas b(&f); // b has a Foo ptr, but should it delete it?
}
したがって、ポインター データ メンバーが自動的に削除されるのはあまり意味がないことがわかります。
原則として、クラスがリソースを管理する場合は1、コピーの作成と割り当てに注意する必要があります。つまり、クラスにとって意味がある場合はそれらを無効にするか、コンパイラが生成したものは機能しないため、それらの実装を提供する必要があります。このトピックに関する詳細な議論については、3 つのルールと、stackoverflow に関する広範な議論を参照してください。
この規則に従わない場合、デフォルトのコピー コンストラクターと代入操作によって浅いコピーが作成され、同じ動的に割り当てられたオブジェクトへのポインターを持つ複数のインスタンスが作成され、それらはすべて破棄時に削除されます。
スマート ポインタnew
を使用して、で作成されたオブジェクトを手動で削除することを回避できます。クラスが明らかに動的に割り当てられたオブジェクトを所有している場合、C++ 11 のstd::unique_ptrまたはboost::scoped_ptrを確認する必要があります。
最後に、本当に必要な場合を除き、ポインターをすべて一緒に回避することで、すべてのメモリ管理の問題を実際に回避できます。たとえばchar*
、次のように置き換えることができます。std::string
class test{
std::string p;
SomeClass someObject;
//test() : someObject() {} // default construction is probably OK...
};
1. つまり、メモリの割り当てと割り当て解除、ネットワーク接続の開閉、ミューテックスの作成と破棄などを行います。