9


3

VC 8でauto_ptrを置き換える
VC 8では `std

auto_ptr`が壊れています(これが職場で使用しているものです)。 それに対する私の主な不満は、それが `auto_ptr x = new T();`を許すことです、それはもちろん間違ったことをするのは簡単ですが、恐ろしいクラッシュにつながります。

answerからここで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`をネット上のものに置き換えてください。 このような this Rani Sharoniからのもの(まだ試していない)。

  • 代わりに `boost :: shared_ptr`を使ってください。 もちろん動作しますが、 私が気にしないいくつかの小さなオーバーヘッドになります。 しかし、ポインタの意図を知らせるために `auto_ptr`を使いたいのです。 (このアプローチの投票についてはhttps://stackoverflow.com/questions/197048/idiomatic-use-of-stdautoptr-または-only-use-sharedptr#197083[この]回答をご覧ください。)

  • 実際に所有権を渡す必要はないので、心配する必要はありません これについて。

'' '' '

更新日:これが私がしたことです:私はRani Sharoniによる前述のauto_ptr実装をコピーしました。 http://groups.google.com/group/comp.std.c / msg / 97a2539a1bbbe491 [ここから]。

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

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

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

もちろん、これらのテストは決して網羅的なものではないので、それらを信頼するべきではありません。 例外セーフなテンプレートクラスを実装するのは毛深いビジネスです。 少なくともこれは内蔵のものよりもうまく機能します。

Note: I don’t know if I’m allowed to use this まだ実装、著作権に関して。 私はRaniに電子メールを送り、返事を待っています。 詳細がわかり次第、この記事を更新します。 Rani Sharoniのauto_ptr実装をあなたが望むとおりに使用することを誰にでも許可します。

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

7 Answer


7


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

当面の間は、古い/別のSTLからauto_ptrの実装を抽出することをお勧めします。そのため、コードが機能します。

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

unique-ptrは、releaseを実行することで所有権を放棄するだけでなく、RHSをnullに設定することで、それを "修正"します。 これはauto-ptrに最も近い代替品ですが、意味が異なるため、ドロップイン代替品ではありません。

http://www.codeproject.com/KB/stl/boostsmartptr.aspx[ブーストスマートポインタ]の紹介記事があります。


3


http://www.stlport.org/[STLPort]の使用を検討しましたか?


2


unique_ptrを使用してください。 私はこれらがより良いauto_ptrであるために導入されたと思います。

実際、私はauto_ptrが廃止予定になっている可能性があると信じ込んでいます。


1


std

auto_ptr <>が壊れていると思うのはなぜですか。

それでも、規格に報告されていたのと同じくらい悪いことがあったかもしれません。

あなたがする必要があるということですか:

std :: auto_ptr x(新しいT); //明示的コンストラクタを使用する


0


boost

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

編集:ここで関連する議論を見つけてください:https://stackoverflow.com/questions/197048/idiomatic-use-of-stdautoptr-or-only-use-sharedptr


0


私が思い出す限りでは、そうではなかった:

auto_ptr x = auto_ptr(new T()); ?


0


答えではありませんが、これらのバグが関係している人の一般的な利益のためです。 VC8の `auto_ptr`にはhttps://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=319580 [さらに関連するバグ]がありますが、これは暗黙のアップキャストと関係があります。 他のバグでは失敗しないで標準に従って違法であるコードをコンパイルすることを可能にするだけで、おそらくそれはおそらく最も厄介なことですが、少なくとも準拠コードは問題なく動作します。 このバグにより、実際に準拠しているコードは正しく動作しません。

問題はこれです。 標準は、通常のポインタと同じように、 auto_ptr`の暗黙のアップキャストをサポートするように auto_ptr`コンストラクタと変換演算子を指定します。 しかし、それのVC8実装はそこでは static_cast`よりもむしろ reinterpret_cast`をします。 当然、これだけではありません。 標準の文字ではなく、それはまた、複数の基本クラスや仮想継承で壊れます。 これはこれによって壊れた合法的なコードの例です:

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

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

std::auto_ptr base2(createDerived());

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