6

T* を使用することは決して最良のアイデアではないという回答がいくつかある質問に出くわしました。

私はすでに RIIC を多用していますが、私のコードには、T* を使用する特定のポイントが 1 つあります。いくつかの自動ポインターについて読んでいますが、それを使用することで明確な利点があると言えるものを見つけることができませんでした。

私のシナリオ:

class MyClass
{

  ...
  // This map is huge and only used by MyClass and 
  // and several objects that are only used by MyClass as well.
  HashMap<string, Id> _hugeIdMap;
  ...
  void doSomething()
  {
    MyMapper mapper;
    // Here is what I pass. The reason I can't pass a const-ref is
    // that the mapper may possibly assign new IDs for keys not yet in the map. 
    mapper.setIdMap(&_hugeIdMap);
    mapper.map(...);
  }
}

MyMapperこれは、HashMap<...>*無関係な問題に関する質問の投票数の多い回答によると、決して良い考えではありません (ただし、マッパーはインスタンスの前に範囲外になるため、MyClassあまり問題ではないと考えています.newマッパーには no があり、 noはdelete必要ありません)。

では、この特定のユースケースで最良の代替手段は何ですか?

4

3 に答える 3

8

個人的には、生のポインタ(または参照)はここで大丈夫だと思います。スマートポインタは、ポイントされたオブジェクトの存続期間の管理に関係しており、この場合MyMapper、そのオブジェクトの存続期間を管理していませんMyClass。また、動的に割り当てられていないオブジェクト(この場合はハッシュマップではない)を指すスマートポインターを使用しないでください。

個人的には、次のようなものを使用します。

class MyMapper
{
public:
    MyMapper(HashMap<string, Id> &map)
        : _map(map)
    {
    }
private:
    HashMap<string, Id> &_map
};

これによりMyMapper、代入演算子が使用できなくなり、コンストラクターでHashMapを渡すことが許容できる場合にのみ機能することに注意してください。それが問題になる場合は、メンバーをポインターにします(ただし、引数を参照として渡し、_map(&map)初期化子リストで行います)。

MyMapperまたはハッシュマップを使用する他のクラスが長生きする可能性がある場合はMyClass、スマートポインターについて考え始める必要があります。その場合、私はおそらくお勧めstd::shared_ptrしますが、どこでもそれを使用する必要があります。通常の非ポインタフィールドではなく、動的に割り当てられた値に対してで_hugeIdMapある必要があります。shared_ptr


アップデート:

プロジェクトのコーディング標準のために参照を使用することは受け入れられないとおっしゃっていたので、上記の理由から、生のポインターを使用することをお勧めします。

于 2011-07-20T12:27:57.277 に答える
1

ネイキッド ポインター (通常は raw ポインターと呼ばれます) は、オブジェクトがオブジェクトを削除する責任を負わない場合に問題ありません。MyMapper の場合、ポインターは MyClass が既に所有しているオブジェクトを指しているため、削除しなくてもまったく問題ありません。問題が発生するのは、生のポインターを使用してオブジェクトを削除するつもりであるときに生のポインターを使用すると、問題が発生する場所です。人々は問題がある場合にのみ質問をします。そのため、ほとんどの場合、問題のあるコンテキストでのみ使用されていることがわかりますが、所有していないコンテキストでの生のポインターは問題ありません。

于 2011-07-20T12:40:33.717 に答える
0

それをコンストラクターに渡し、それへの参照 (または const 参照) を保持するのはどうですか? そうすれば、オブジェクトを所有しないという意図が明確になります。

自動ポインタまたは共有ポインタを渡すことは、主に所有権を伝達するためのものです。

  • 共有ポインタは共有されていることを示します
  • 自動ポインターは、それが受信者の責任であることを示します
  • 参照は、それが送信者の責任であることを示しています
  • 空白のポインタは何も示しません。

あなたのコーディング スタイルについて:

私たちのコーディング標準には、非 const 参照を決して渡さないという規則があります。

C++ 参照メカニズムまたは C++ ポインター メカニズムのどちらを使用する場合でも、変更される内部ストレージへの (英語の意味での) 参照を渡します。あなたのコーディング標準は、参照を使用してそうすることができないほどではなく、別の方法でそれを行うことができるように、それをまったく行わないように伝えようとしていると思います。

于 2011-07-20T12:46:38.723 に答える