0

そのため、一種のデータ構造にマップとキー クラスを使用する C++ クラスがいくつかあります。私の挿入メソッドでは、典型的な map.insert を使用します。挿入された要素内のいくつかの値 (比較に使用されるものではない) を変更できるように、この関数がポインターを返すようにします。だから私はこれがこれに安全かどうか疑問に思っていました..

template<typename T>
NodeT<T> *  TreeT<T>::
MakeNode(PointT point)
{
  NodeT<T> * prNode = new NodeT<T>;

    //set the contents for the node
  prNode->SetNode(point, m_dTolerance);


  //Create the key class using the 
  VectorKey key(point, m_dTolerance);

  //Store the key,node as a pair for easy access 
  return_val = m_tree.insert( pair<VectorKey, NodeT<T> >(key, *prNode) );
  if (return_val.second == false)
    //if return_val.second is false it wasnt inserted
    prNode = NULL;
  else
   //it was inserted, get a pointer to node
    prNode = &(return_val.first->second); //is this safe if I plan to use it later?

  return prNode;

}

元のポインター (new で作成したポインター) が、挿入後に間違った要素を指していたという難しい方法を学んだようです。その理由を誰か教えてもらえますか?そこで、return_val イテレーターを使用して正しいポインターを取得しました。私はちょっとイテレータを返したくありませんが、より安全であればそうします...

ありがとう!

4

3 に答える 3

1

このコード サンプルは興味深いものです。

実装

最も重要なことは (主に Bogolt によって) 述べられています。

  • ポインターではなくオブジェクトのコピーを割り当てるためNodeT<T>、ヒープから割り当てて再度解放しないため、メモリリークが発生しています。map実際、*prNodeではなくパラメータとして指定しますprNode
  • ヒープを使用してオブジェクトを割り当てますが (にコピーされますmap)、常にオブジェクトを割り当てると想定しています。最も可能性の高いケースですが、常にそうであるとは限りません。new演算子は null を返すか、bad_alloc例外をスローします。コードはそれを処理しません。
  • とにかく、本当に必要ないときはヒープを使用します。(そして、あなたは問題があなたが導入していることがわかります)。スタックにオブジェクトを作成してからマップに挿入するだけで、以前の問題を回避し、コードの入力を減らすことができます。

デザイン

  • この関数は、マップ内の要素へのポインターを返します。プログラムによっては、これが安全である可能性があります。しかし、オブジェクトがマップから削除されたときにコードがポインターを参照するとどうなるでしょうか? ポインターを返す場合は、生のポインターを返さない方がよいでしょう。代わりにスマート ポインター (shared_ptrこの場合) を使用します。あなたを使用shared_ptrして、オブジェクトの寿命に問題はありません。
  • スマート ポインターを使用するその他の理由: マップへの挿入は要素のコピーを意味するため、次の要件を課していますNodeT<T>: コピー構築可能である必要があります。この要件はパフォーマンスにとって重要ではないかもしれませんが、他の状況ではオブジェクトのコピーに欠点があるかもしれません。スマート ポインター (またはboost::ptr_map) を使用すると、オブジェクトは 1 回だけ作成され、コピーされません。

スタイル

いくつかの提案ですが、それほど重要ではありません:

  • 代わりに type pair<VectorKey, NodeT<T> >(key, *prNode)、 type make_pair(key, *prNode). コードはよりコンパクトで明確になり、タイピングが少なくなります。
于 2013-06-10T07:41:24.837 に答える