8

fooコンストラクトをコピーしたい std::auto_ptr メンバーを含むクラスがありますが、これは許可されていないようです。課題についても同様のことがあります。次の例を参照してください。

struct foo
{
private:
    int _a;
    std::string _b;
    std::auto_ptr< bar > _c;

public:
    foo(const foo& rhs)
        :   _a(rhs._a)
        ,   _b(rhs._b)

        ,   _c(rhs._c)
                // error: Cannot mutate rhs._c to give up ownership - D'Oh!
    {
    }

    foo& operator=(const foo& rhs)
    {
         _a = rhs._a;
         _b = rhs._b;

         _c = rhs._c;
             // error: Same problem again.
    }
};

_casと宣言することもできますmutableが、これが正しいかどうかはわかりません。誰かがより良い解決策を持っていますか?

編集

OK、期待していたような回答が得られないので、問題についてもう少し具体的に説明します。

  • タイプのオブジェクトがfooスタック上に作成され、値によってコンテナー クラス (stl ではない) に渡された後、スコープ外になります。コンテナー コードを制御することはできません。(実際には、バグのあるアクティブ キューの実装です。)
  • このbarクラスは、かなり重量のあるパーサーです。パフォーマンスが非常に低いnewためdelete、コピー構築可能であったとしても、コストがかかりすぎます。
  • barオブジェクトが作成されると、一度に 1 か所だけ所有する必要があることを保証できます。この場合、スレッド間で渡され、トランザクションが完了すると削除されます。これが、私が a を使用することを望んでいた理由ですstd::autp_ptr
  • ブースト スマート ポインターを検討したいと思っていますが、代替手段があれば、この一意性を保証したいと考えていました。
4

9 に答える 9

16

次のコードを試してみてください。

    foo(const foo& rhs)
        :   _a(rhs._a)
        ,   _b(rhs._b)
        ,   _c(_rhs._c.get() ? new bar(*_rhs._c.get()) : 0)
    {
    }

(代入演算子も同様です。)

ただし、これbarは CopyConstructible であり、これが実際に必要な場合にのみ機能します。問題は、両方のfooオブジェクト (_rhsおよび構築されたもの) が異なるポインターを持つこと_cです。

ポインターを共有したい場合は、auto_ptr所有権の共有をサポートしていないため、使用しないでください。このような場合、たとえばshared_ptrfrom Boost.SmartPtrの使用を検討してください (これは新しい C++ 標準に含まれます)。または、これは非常に一般的な概念であるため、他の共有ポインターの実装であり、多くの実装が利用可能です。

于 2009-07-17T11:25:49.953 に答える
8

あなたが発見したstd::auto_ptrように、そのようなコピーはできません。コピーの後、指し示したオブジェクトの所有者は誰ですか? 代わりに、参照カウント スマート ポインターを使用する必要があります。Boost ライブラリには、使用できるshared_ptrがあります。

于 2009-07-17T11:21:47.263 に答える
1

auto_ptr を含むクラスがあり、ディープ コピーのセマンティクスが必要な場合、通常は、仮想コピー演算子、つまり clone() を持つクラスに対してのみこれを行います。

次に、コピー コンストラクター内で、auto_ptr を他の clone() に初期化します。例えば

class Foo
{
   public:
      Foo(const Foo& rhs) : m_ptr(rhs.m_ptr->clone());
   private:
      std::auto_ptr<T> m_ptr;
};

clone() は通常、次のように実装されます。

class T
{
   std::auto_ptr<T> clone() const
   {
      return std::auto_ptr<T>(new T(*this));
   }
};

T が複製可能であるという条件を課していますが、この条件は基本的に auto_ptr メンバーを持つコピー可能なクラスを持つことによって課されます。

于 2009-07-17T17:59:17.923 に答える
0

編集を考えると、所有権のセマンティクスの譲渡が必要なようです。

その場合、コピー コンストラクターと代入演算子が引数への非 const 参照を受け入れ、そこで初期化/代入を実行する必要があります。

于 2009-07-17T18:04:36.557 に答える
0

私の最初の選択は、この状況で auto_ptr を完全に避けることです。しかし、壁にぶつかった場合はmutable、_c の宣言でキーワードを使用しようとするかもしれません。これにより、const 参照からでも変更できるようになります。

于 2009-07-17T15:17:39.827 に答える
-1

を含むコピー コンストラクターまたは代入演算子で const 参照を使用することはできませんauto_ptr<>。コンストを削除します。つまり、次のような宣言を使用します

foo(foo & rhs);
foo & operator=(foo & rhs);

これらの形式は、標準の主にセクション 12.8 で明示的に言及されています。それらは、標準に準拠した実装で使用できるはずです。実際、12.8 の段落 5 と 10 は、メンバーのいずれかがそれを必要とする場合、暗黙的に定義されたコピー コンストラクターと代入演算子 (それぞれ) が非 const 参照を取ると述べています。

于 2009-07-17T15:30:36.947 に答える