0

new キーワードを使用してメインでオブジェクトを作成し、そのオブジェクト (ポインター) を別のクラスのメンバーが指すように設定し、元のポインターを null に設定すると、割り当てられたメモリはどこで削除されるのでしょうか? 2 番目のクラスのデストラクタで実行できますが、そのオブジェクトが動的に割り当てられていない場合はどうでしょうか。

例としていくつかのコード:

World world;
Player* newPlayer = new Player("Ted");
world.setPlayer(newPlayer);
newPlayer = 0;

そのため、World の「player」メンバー変数は newPlayer によって割り当てられたメモリを指し、newPlayer は null を指しています。World オブジェクトを使い終わったら、このメモリの割り当てを解除するにはどうすればよいですか?

4

5 に答える 5

6

この種の複雑さは、C++ で生のポインターを避けるようにする必要がある理由です。 この種の問題を解決するためにスマート ポインターが存在し、オブジェクトの所有者と削除時期を手動で追跡する手間を省くことができます。

例えば:

typedef boost::shared_ptr<Player> sp_Player;

struct World {
    sp_Player player;
    World(sp_Player p) : player(p) {}
};


sp_Player newPlayer = new Player("Ted");

World world;
world.setPlayer(newPlayer);

// Object is now automatically deleted at the correct time!
于 2012-07-12T10:22:35.700 に答える
3

他の回答で述べたように、スマートポインターを使用する方が簡単ですが、この場合、削除を別の場所に置くことができます。

すべてのプレーヤーが に渡された場合World、メモリを処理できます。 aが破壊さWorldれるたびに、または別のプレーヤーが設定されるたびに、保持されている を削除する必要があります。また、プレーヤーは他の場所で破壊されるべきではありません。そうしないと、2 回破壊される可能性があります。ただし、この場合、すべての Player をメソッドによって構築して、誰がメモリ管理を所有しているかを明確にし、同じクラスで Player オブジェクトの作成と破棄を行うようにします。WorldPlayerWorldWorld

いくつかの非常に不完全なコードがあります (スマート ポインター コードがはるかに少なく、すべてのケースをカバーしていると思います - これはそうではありません)。

class World
{
   Player *p;
 ...
}

World() : p(nullptr) {
  ...
}

~World() {
    delete p;
}

void World setPlayer( Palyer *aP ) {
    if ( p != aP) {
         delete p;
    }
    p = aP;
    ....
}

Player* World::createPlayer(std::string const& name){ 
  return new Player(name); 
} 

Note= Player(name)はスタック上に Playeobject を作成しますが、これは new と delete によってコード内で管理されません。ここでの最良の解決策かもしれません。

また、operator= とコピー コンストラクターを処理する必要があります (後者の場合は、呼び出されないようにするか、Player オブジェクトを複製する必要があるため、Original World とコピーの両方が同じ Player を削除しようとすることはありません)。

于 2012-07-12T10:26:30.170 に答える
1

絶対的な答えはありません。問題は、そもそもオブジェクトを動的に割り当てる理由です。これに答えたら、通常は削除すべき場所が明らかです。

worldたとえば、オブジェクトの名前から、それがすべてを所有していると思います。プレーヤーの寿命などを決定すること。その場合、delete. スタックにa を割り当てる可能性については、Personそうしないでください。おそらく、関数内のブロックに対応しないPerson確実な有効期間があることを考えると (それ以外の場合は、そもそも動的に割り当てる理由)、その型のローカル変数を宣言する意味がありません。

于 2012-07-12T10:39:06.910 に答える
0

終了したら、 delete を呼び出すだけです。ただし、この必要性を回避するには、共有ポインターを使用することを検討してください。共有ポインターを使用すると、これを行う必要がなくなります。

編集:コメントに答えるには、どこに電話deleteするかはアプリケーションによって異なりますが、

  1. 割り当てるdelete前にしないでください。
  2. deleteにアクセスする必要がないことを確認するまでは、使用しないでください。

可能性のある場所は World オブジェクトのデストラクタにありますが、アプリケーションの残りの部分の詳細を知らずに言うことはできません。boost::shared_ptrこれが好ましい理由です。

于 2012-07-12T10:22:54.217 に答える
-1

new の後には常に delete を指定する必要があります。メモリを解放せずに他のオブジェクトを指すようにポインタを設定すると、ダングリング ポインタが発生します。

于 2012-07-12T10:21:25.417 に答える