デストラクタと呼ばれるオブジェクトを追加する場合にもstd::一覧
-
21-08-2019 - |
質問
いFooオブジェクトでは、std::リスト保持のインスタンスです。私の問題は時を追加する新しいインスタンスのリストで最初のctorのものdtor.そのdtor別のインスタンスとなっている(このポインタ.
単一のインスタンスがリストに追加されますが、そのdtor(その親)が呼ばれるオブジェクトだとして期待される。
ニも簡単なコードを説明するための問題:
#include <iostream>
#include <list>
class Foo
{
public:
Foo()
{
int breakpoint = 0;
}
~Foo()
{
int breakpoint = 0;
}
};
int main()
{
std::list<Foo> li;
li.push_back(Foo());
}
解決
は、オブジェクトが呼び出され、リストの内部データ構造、したがって、デストラクタと別のインスタンスのCTORへのコピーのです。
Cのすべての標準のSTLコンテナタイプは、値によってそのアイテムを取る必要に応じので、それらをコピー++。ベクトルが成長する必要があるとき例えば、ベクトル内のすべての値がコピーされます可能性があります。
は、たぶん、あなたが保存したいのポインタの代わりに、リスト内のオブジェクトの。それを行うことにより、ポインタだけではなく、オブジェクトのコピーされます。しかし、そうすることによって、あなたはあなたが完了したらオブジェクトを削除することを確認する必要があります:
for (std::list<Foo*>::iterator it = list.begin(); it != list.end(); ++it) {
delete *it;
}
list.clear();
また、あなたがBoostライブラリから、たとえば、「スマートポインタ」クラスのいくつかの種類を使用しようとすることができます。
他のヒント
あなたがここに一時的にはFooを作成しています:
li.push_back( Foo() )
その内部データ構造にはFoo 一backコピー。一backが実行された後、一時はFooはデストラクタを呼ぶであろう、破壊されます。
あなたが早期に破壊したくないクラスメンバーにいくつかの参照カウントを増加させ、適切なコピーコンストラクタが必要になります - またはポインタソリューションに自分自身を強制することは、民間作る
。理解するためにこのオブジェクトを使用します:
class Foo
{
public:
Foo(int x): m_x(x)
{
std::cout << "Constructed Object: " << m_x << ")\n";
}
Foo(Foo const& c): m_x(c.m_x+100)
{
std::cout << "Copied Object: " << m_x << ")\n";
}
~Foo()
{
std::cout << "Destroyed Object: " << m_x << ")\n";
}
};
まずメイン
std::list<Foo*> li;
li.push_back(Foo(1));
ここでは、一時的なFooのオブジェクトを作成して)(一back呼び出します。一時オブジェクトは、リストと関数の戻りにコピーされます。このステートメントの完了時に、一時的なオブジェクトは、(デストラクタを経由して)破棄されます。リストには、それはまた、それに含まれるすべてのobejctsを破壊する破壊された場合(破壊がデストラクタを呼び出す含まれてfooはデストラクタを持つオブジェクトです)。
ですから、このような気にいらが表示されます
Constructed Object: 1
Constructed Object: 101
DestroyedObject: 1
DestroyedObject: 101
あなたが持っている2番目の例でます:
std::list<Foo*> li;
li.push_back(new Foo(1));
ここでは、動的に、ヒープ上のオブジェクトを作成します。そして、一back()を呼び出します。ここでは、ポインタがリストにコピー(ポインタがコンストラクタ/デストラクタを持っていない)ので、他には何も起こりません。リストには現在、ヒープ上のオブジェクトへのポインタが含まれています。関数は他に何も返さないときに行われます。リストが破壊された場合、それが含まれているオブジェクト(ポインタ)(微妙な差が破棄および削除ビトウィーンズ注意)破壊するが、ポインタは何のデストラクタを持っていないので、何もいずれかを起こりません、あなたはメモリリークが発生します。
ですから、このような気にいらが表示されます
Constructed Object: 1
ど実際に起こっていることはでき店 コピー 渡されたオブジェクトのリストでだけ送信する価値ではなく、参考にする。そこで第一にdtorと呼ばれる実際には、オブジェクトに渡しますのpush_back方法が、新しいインスタンスが作成されているという長いリストに保存されます。
場合によってお使いのコピー Foo オブジェクトを作成し、店舗へのポインタ Foo オブジェクトリストの代わりにオブジェです。もちろんがっきにおいて、適切にリリース上のメモリ破壊をクリックします。
ポインタの代わりにインスタンスを保持するリストを作成デストラクタが呼び出されるとの問題を解決します。しかし、私はまだそれがなぜ起こるか理解したい。
#include <iostream>
#include <list>
class Foo
{
public:
Foo()
{
int breakpoint = 0;
}
~Foo()
{
int breakpoint = 0;
}
};
int main()
{
std::list<Foo*> li;
li.push_back(new Foo());
}