1

私はプライベートフィールドを持っています

std::map<std::string, std::multiset<GraphObject*>>* the_Map;

メモリを割り当てて GraphObject を挿入するにはどうすればよいですか? new 演算子を使用する必要がありますか?

the_Map = new map<string,multiset<GraphObject*>>;

また、新しい GraphObject を挿入するにはどうすればよいですか? これはデータ構造の一部であり、マップへのポインターが本当に必要です。

4

2 に答える 2

2

どうすればメモリを割り当ててGraphObjectを挿入できますか?

ポインタにはなりたくありません。マップ自体をクラスのメンバーにするだけで、メモリの割り当てが自動的に行われます。

オブジェクトもそこに格納しているので、オブジェクトを正しく挿入するのはかなり面倒です。ポインタである必要がない場合は、オブジェクトを保存すると、作業がはるかに簡単になります。それが本当にポインタである必要がある場合(たとえばGraphObject、多態的な基本クラスであるため)、スマートポインタを格納することをお勧めします:std::unique_ptr、またはstd::tr1::shared_ptr過去boost::shared_ptrに行き詰まっている場合。

本当に、なんらかの理由で生のポインタを使用する必要がある場合、例外安全な挿入に最も近いのはおそらく次のとおりです。

GraphObject * object = new Whatever(...);
try {
    the_Map[key].insert(object);
} catch(...) {
    delete object;
    throw;
}

または、挿入の失敗時にメモリリークが発生する可能性を気にしない場合:

the_Map[key].insert(new Whatever(...));

また、オブジェクトを削除するときは、各オブジェクトを削除することを忘れないでください。それは自動的には起こりません。

私は本当に地図へのポインタが必要です。

いいえ、しません。しかし、あなたが本当にそう信じていて、そうしないようにみんなのアドバイスを無視したいのなら、あなたはそれを指す実際の地図が必要になるでしょう。このマップをクラスのメンバーにして、その存続期間が自動的に管理されるようにすることをお勧めします。

あなたが本当にコードを維持する人の生活を困難にしたいのなら、私はあなたがコードを割り当てることができると思いますnew。その場合は、使い終わったら削除することを忘れないでください。おそらくクラスデストラクタにあります。その場合は、三つのルールを覚えて、コピーコンストラクターとコピー代入演算子を実装または削除してください。デフォルトの実装では間違った処理が行われるためです。

于 2013-01-09T14:56:54.487 に答える
2

::std:multisetを保存している理由GraphObject *は少しわかりにくいですが、それでロールバックしましょう。

これは、ドキュメントで本当に簡単に答えられる答えですが、StackOverflowにとってあまりにも愚かな質問はないので...

 the_Map = new map<string,multiset<GraphObject*>>;

それが実際に、マップにメモリを割り当てる方法です。周りにあるものへの裸のポインタを持つことは一般的に良い考えではありませんが、あなたは主張しました、そしてそれがあなたのやり方です. deleteそれは、ある時点でそれを覚えておく必要があることを意味します。そして、ポインターを保持するクラスのコピー構造が正しいことを行うことを確認する必要があります (正しいことはかなり複雑になります)。

あなたは今、興味深い問題を抱えています。multiset各マップ エントリにを格納しています。幸いなことに、このマルチセットは自動的に作成され、未知のキーがアクセスされると空に初期化されます。OTOH、ベアポインターの使用は、例外の安全性の問題があることを意味します。途中で例外がスローされると、メモリ リークが発生する可能性があります。したがって、例外をキャッチしてオブジェクトをクリーンアップする必要があります。

 GraphObject *tmp = new GraphObject;
 try {
     (*the_Map)[key].insert(tmp);
 } catch (...) {
     delete tmp;
     throw;
 }

あなたの質問が非常に基本的なものであるという事実は、ポインターを使用する必要があるというあなたの主張に疑問を投げかけます. そして、 from ->multimapではなくa を使用したくないのではないかと本当に思います。ただし、データ構造の一般的な形式については固執しています。以上が使用方法になります。mapstringmultiset

また、このデータ構造で生のポインターを大量に使用することは、かなり悪い考えだとも言います。混乱全体を適切に分解またはコピーするには、かなり洗練された関数を作成する必要があります。

編集:ため息午前 4 時に自分で作成したことのないデータ構造をコーディングすると、非常にばかげたコードを書くことになりました。現在のバージョンははるかに優れています。この答えは私のものよりもはるかに優れていますが。

于 2013-01-09T14:41:10.300 に答える