11

こんにちは、

スマートポインタに関するこのクエリがあります。

友人の一人から、スマートポインターはほとんどの場合生のポインターを置き換えることができると聞きました。しかし、私が彼にスマートポインターが生のポインターを置き換えることができない他のケースは何であるかを尋ねたとき、私は彼から答えを得ませんでした。

誰かが生のポインタをいつどこで置き換えることができないか教えてもらえますか?

4

7 に答える 7

11
  1. レガシーAPIへのポインターの受け渡し。
  2. 参照カウントされたツリー構造での逆参照(または、さらに言えば、循環的な状況)。あなたがweak-refsを使うことができるので、これは議論の余地があります。
  3. 配列を反復処理します。

スマートポインタを使用できるが、使用したくない場合も多くあります。例:

  1. 一部の小さなプログラムは、すべてをリークするように設計されています。これは、自分でクリーンアップする方法を理解するという複雑さを追加するだけの価値がないためです。
  2. パーサーなどのきめ細かいバッチアルゴリズムは、事前に割り当てられたメモリプールから割り当て、完了時にプール全体を吹き飛ばす場合があります。そのようなプールへのスマートポインタを持つことは通常無意味です。
于 2010-04-07T14:19:58.500 に答える
3

Cから呼び出されるAPIは、明らかな例です。

于 2010-04-07T14:20:32.420 に答える
3

使用するスマートポインタによって異なります。std::auto_ptrはSTLコンテナと互換性がありません。

于 2010-04-07T14:24:05.857 に答える
3

それはセマンティクスの問題です:

  • スマートポインタ:あなたは(少なくとも部分的に)ポイントされているメモリを所有しており、それ自体がそれを解放する責任があります
  • 通常のポインタ:オブジェクトへのハンドルが与えられています...またはそうではありません(NULL)

例えば:

class FooContainer
{
public:
  typedef std::vector<Foo> foos_t;

  foos_t::const_iterator fooById(int id) const; // natural right ?
};

ただし、ここで実装の詳細を公開すると、独自のイテレータクラスを完全に作成できます...ただし、イテレータは通常、インクリメント可能などを意味します...またはポインタを使用します

class FooContainer
{
public:
  const Foo* fooById(int id) const;
};

おそらくNULL、失敗を示すを返すか、メモリを処理する必要のないオブジェクトへのポインタを返します。

もちろん、weak_ptrここで使用することもできます(メソッドを取得しますexpired)が、shared_ptrそもそも使用する必要があり、実装で使用しない場合があります。

于 2010-04-07T14:49:29.013 に答える
2

レガシーコードとの相互作用。APIに生のポインターが必要な場合は、コードに一度生のポインターを入れたら、それをスマートポインターでラップする場合でも、生のポインターを提供する必要があります。

于 2010-04-07T14:21:12.023 に答える
1

生のポインターが何らかの理由でintptr_tにキャストされて戻ってくる状況では、キャスト操作によってスマートポインターに含まれる参照カウント情報が失われるため、スマートポインターに置き換えることはできません。

于 2010-04-07T14:21:44.853 に答える
1

ある時点でプレーンポインタを使用しない場合、スマートポインタを実装するのは非常に困難です。

スマートポインタを使用して特定のデータ構造を実装することも難しいと思います。たとえば、通常のリンクリストのメモリを解放することは非常に簡単ですが、同じ結果を得るには、所有しているスマートポインタと所有していないスマートポインタの組み合わせを理解する必要があります。

于 2010-04-07T15:12:49.903 に答える