3

だから私が持っていると言う

foo* fooObject1 = new foo[10];
// here would go code for initializing fooObject1[0] to fooObject1[9] with a foo object for each.
foo* fooObject2 = new foo[30];

for(int = 0; i < 10; i++)
fooObject2[i] = fooObject1[i];

if(fooObject1 != NULL)
delete[] fooObject1; //this "destroys" the array, BUT ALSO calls the destructors of all the foo objects inside fooObject1, causing fooObject2 elements to be anything but what it was before.

fooObject1 = fooObject2;

wherefooは、それぞれのメソッドで私が作成した特定のオブジェクトです。

ただし、ここでの問題は、配列の要素ではなく、fooObject1 が指す配列を破棄したいということです。それを C++ で行う方法はありますか? 問題を回避する別の方法は、= (等号) 演算子をオーバーロードすることですが、それが必要なプログラムでは、他の多くのクラスの他の多くの = 演算子をオーバーロードすることを含む書き込みで、退屈で長いプロセスになります。 . 何らかの方法でオブジェクトを fooObject2 に保持し、fooObject1 が指す配列を取り除くことを望んでいました。それで、これはできますか?どのように?そうでない場合、それについて読むために私をリダイレクトできるウェブサイトはありますか?

4

4 に答える 4

2

fooObject1 を指す配列には、オブジェクトが含まれています。あなたは大工に本棚を破壊するように頼んでいますが、棚には本を置いたままにしておいてください. (できればナイストリックです。)

for ループで、オブジェクトを fooObject1 から fooObject2 にコピーします。したがって、fooObject2 にはさまざまなオブジェクトが含まれています。

オブジェクトをコンテナーから独立させたい場合は、ポインターを使用する必要があります。

于 2012-09-29T04:44:07.147 に答える
2

これら独立しています。fooObject2 配列は fooObject1 と同じように割り当てられ、代入演算子は途中でそれぞれに対して起動されます。fooObject2 の fooObject1 からの各オブジェクトのコピーを効果的に持っています。

fooObject1 を放棄することはできません。[] を削除する必要があります。そうしないと、メモリ リークが発生します。書かれているように、fooObject2 は独立しています。ただし、fooObject クラスに内部ポインターがあり、 Rule of Threeに従わなかったために浅いコピーが実行された場合を除きます。

この最後の行は、fooObject1 をクリーンアップし、以前のメモリ割り当てを削除した後、fooObject2 と同じオブジェクトを指すように fooObject1 (ポインター) を設定します。1つだけ削除してください。

于 2012-09-29T04:47:35.247 に答える
1

最新の C++テクニックとコンテナー(生の例外、安全でないリークが発生しやすい、および生のポインターstd::vectorの代わりに)を使用することをお勧めします。 new[]delete[]

オブジェクトへのポインターの配列が必要で、これらのオブジェクトをこれらの配列間で共有しfooたい場合は、 .foovector<shared_ptr<foo>>

shared_ptrは、参照カウントを使用するスマート ポインター テンプレート クラスであり、オブジェクトへの最後の参照が解放されたときにのみ、ポイントされたオブジェクトを破棄します。

アロケータを使用make_sharedして の新しいインスタンスをインスタンス化しfoo、 を使用して (動的) 配列に配置できますvector::push_back()

例えば

#include <vector> // std::vector
#include <memory> // std::shared_ptr, std::make_shared

using namespace std;

// Smart pointer to foo
typedef shared_ptr<foo> foo_ptr;

// Dynamic arrays of smart pointers
typedef vector<foo_ptr> foo_array;

// Define an array of smart pointers to foo
foo_array v1;

// Populate the array
v1.push_back( make_shared<foo>( /* some constructor init params */ ) );
v1.push_back( make_shared<foo>( /* ... */ ) );

// Create another array of smart pointers to foo's
// and reference the foo's created in v1
foo_array v2 = v1;

// Empty the array of smart pointers 'v1'.
// However, the 'foo' objects previously created are still "alive",
// because of the references stored in 'v2'.
v1.clear();

最新のC++ 手法を使用することに注意してください。明示的な delete;はありません。STL コンテナ、スマート ポインタ、および C++ デストラクタの機能により、リソースは自動的に管理されます。コードはリークフリーで例外セーフであり、読みやすく維持しやすいです。

于 2012-09-29T10:21:14.000 に答える
1

C++ では、配列はオブジェクトではありません。あなたが持っているのは、 を呼び出したためにnew[]、たまたま n 個の連続して割り当てられたオブジェクトの先頭を指している 2 つのポインターです。配列を削除したり、オブジェクトを削除したりすることはできません。配列は、オブジェクトが配置されている連続したメモリです。

ただし、ポインターをクリアすることはできますが、これを行うと、オブジェクトの場所がわからなくなります。これがいわゆるメモリリークです。そのメモリはそれらのオブジェクトに割り当てられており、その場所がわからないため、割り当てを解除できなくなります。

fooObject1からに10 個のオブジェクトの値をコピーしましたfooObject2。それらは異なるオブジェクトであるため、削除fooObject1してもオブジェクトは変更されません。オブジェクトのセットが異なる別のメモリ位置にある別の配列を指します。これらのオブジェクトの値を のオブジェクトの値に割り当てることによって、以前の値を保存しました。fooObject2fooObject2fooObject1fooObject2

于 2012-09-29T04:48:20.903 に答える