9

std::auto_ptrVC++ 8 では壊れています (これは私たちが仕事で使用しているものです)。それに対する私の主な不満は、それが可能auto_ptr<T> x = new T();であることです。これはもちろん恐ろしいクラッシュにつながりますが、誤って行うのは簡単です。

stackoverflow に関する別の質問への回答から:

Visual Studio 2005 での std::auto_ptr の実装はひどく壊れていることに注意してください。 http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=98871 http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101842

使いたい

  • boost::scoped_ptr、所有権を渡してはならないポインタ用。
  • boost::shared_ptr、コンテナー内のポインターおよびポインターが必要な他の場所。
  • std::auto_ptr、所有権を渡す必要がある/渡すことができるポインター用。

しかし、std::auto_ptr私にとっては壊れているので、最善のアプローチは何でしょうか:

  • std::auto_ptrネットで拾ったもので代用。Rani Sharoni のこのようなもの(まだ試していません)。
  • boost::shared_ptr代わりに使用してください。もちろん機能しますが、私が気にしない小さなオーバーヘッドが発生します。auto_ptrしかし、ポインターの意図を知らせるために使用したいと思います。(このアプローチに関する投票については、この回答を参照してください。)
  • 実際には所有権を渡す必要はないので、これについて心配する必要はありません。

更新: これが私がしたことです: Rani Sharoni による前述の auto_ptr 実装をコピーしました。ここから

いくつかのマイナーなテストを行いました:

class T
{
public:
    T() {
        OutputDebugStringA("T\n");
    };
    ~T() {
        OutputDebugStringA("~T\n");
    };
};

{
    fix::auto_ptr<T> x(new T); // This just works.
}
{
    fix::auto_ptr<T> x = (new T); // Doesn't compile. Great!
}
{
    fix::auto_ptr<T> x = fix::auto_ptr<T>(new T); // Transfer of ownership works also.
}

もちろん、これらのテストは決して網羅的なものではなく、信頼すべきではありません。例外セーフのテンプレート クラスを実装することは、毛むくじゃらの仕事です。少なくとも、これは組み込みのものよりもうまく機能します。

注: 著作権に関して、この実装をまだ使用できるかどうかはわかりません。Rani にメールを送信し、返信を待っています。詳細がわかり次第、この投稿を更新します。 誰でも、Rani Sharoni の auto_ptr 実装を自由に使用することが許可されています。

返信ありがとうございます。

4

7 に答える 7

7

スマートポインタをブーストするために移動します。

それまでの間、古い/別のSTLから動作するauto_ptr実装を抽出して、動作するコードを作成することをお勧めします。

auto_ptrのセマンティクスは根本的に壊れていると思います。入力は節約できますが、インターフェースは実際には単純ではありません。現在の所有者がどのインスタンスであるかを追跡し、所有者が最後に離れることを確認する必要があります。

unique-ptrは、リリースを行うことで所有権を放棄するだけでなく、RHSをnullに設定することで「修正」します。これはauto-ptrの最も近い代替品ですが、セマンティクスが異なるため、ドロップインの代替品ではありません。

スマートポインタを後押しするための紹介記事があります。

于 2008-11-07T09:47:14.437 に答える
3

STLPort の使用を検討しましたか?

于 2008-11-06T22:01:30.523 に答える
2

unique_ptr を使用します。これらは auto_ptr を改善するために導入されたと思います。

http://www.boost.org/doc/libs/1_35_0/doc/html/interprocess/interprocess_smart_ptr.html#interprocess.interprocess_smart_ptr.unique_ptr

実際、私は auto_ptr が推奨されていない可能性があると信じています。

http://objectmix.com/c/113487-std-auto_ptr-deprecated.html

于 2008-11-06T22:04:03.777 に答える
1

なぜ std::auto_ptr<> が壊れていると思いますか?

標準化委員会に報告されたのと同じくらい悪いことをしたでしょう!

次のことを行う必要があるということですか。

std::auto_ptr<T>   x(new T);  // Use the explicit constructor.
于 2008-11-06T21:30:17.543 に答える
0

私が覚えている限りでは、そうではありませんでした:

auto_ptr<T> x = auto_ptr<T>(new T()); ??
于 2009-08-06T07:28:22.050 に答える
0

答えではありませんが、これらのバグに関連するすべての人の一般的な関心のために。暗黙的なアップキャストに関係する VC8 の関連バグがもう 1 つありauto_ptrます。他のバグにより、標準に従って違法であるコードを失敗することなくコンパイルできるようになるため、これはおそらく最も悪いことですが、少なくとも準拠したコードは正常に動作します。このバグにより、実際に準拠しているコードが正しく動作しなくなります。

問題はこれです。Standard では、コンストラクターと変換演算子が、通常のポインターと同様に、s のauto_ptr暗黙的なアップキャストをサポートするように指定されています。auto_ptrただし、その VC8 実装は、あるのではreinterpret_castなく、あることを行いstatic_castます。当然のことながら、これは標準の文字による UB であるだけでなく、複数の基本クラスおよび/または仮想継承でも破られます。これによって破られた合法的なコードの例を次に示します。

struct Base1 { int x; };
struct Base2 { int y; };
struct Derived : Base1, Base2 {};

std::auto_ptr<Derived> createDerived()
{
  return std::auto_ptr<Derived>(new Derived);
}

std::auto_ptr<Base2> base2(createDerived());

私の過去の仕事の 1 つで、本番環境でこの問題に遭遇したとき、ヘッダーに自分でパッチを当てるだけで済みました (これは簡単な 2 行の修正です)。

于 2009-08-06T07:42:30.993 に答える
0

boost::shared_ptr/boost::scoped_ptr を使用します。これは、今後の C++ 標準で推奨されるスマート ポインターになります (既に TR1 に含まれています)。

編集: ここで関連する議論を見つけてください: std::auto_ptr の慣用的な使用または shared_ptr のみを使用しますか?

于 2008-11-06T21:30:12.007 に答える