4

私はクラスを持っていMyObjectます。そのすべてのインスタンスは によって所有されるべきでMyObjectSetあり、それを他の場所に構築することはできません。内部では、すべてのインスタンスを格納MyObjectSetするために a を使用しています。std::vector<MyObject>

問題は、 forstd::vector<MyObject>が動作するためには、 のムーブ コンストラクターが public でなければならないことです (のフレンドとしてMyObject追加するだけでは十分ではありません)。std::vector<MyObject>MyObject

class MyObject {
    MyObject(int n);
    friend class MyObjectSet;
  public:
    MyObject(MyObject&&) = default; // without this, it doesn't compile
};

class MyObjectSet {
    std::vector<MyObject> MyObjects;
  public:
    MyObject& GetMyObject(int some_param);
};

しかし公開すればMyObject、どこからでもインスタンス化できるようになります。

void SomeUnrelatedFunc(MyObjectSet& set) {
    MyObject m(std::move(set.GetMyObject(0))); // this shouldn't be possible
}

この問題を解決する方法はありますか?

MyObject代わりにインスタンスへのポインターを内部に格納することは可能ですMyObjectSetが、可能であれば避けたいと思います。

4

2 に答える 2

2

std::allocator<MyObject>友達として宣言する必要があります:

class MyObject {

    MyObject(int n);
    friend class MyObjectSet;
    friend std::allocator<MyObject>;
};

次にvector::emplace_back()、オブジェクトを実際に構築するために使用します。

class MyObjectSet {
    std::vector<MyObject> MyObjects;

public:
    MyObject& GetMyObject(int some_param)
    {
        MyObjects.emplace_back( some_param );
        return MyObjects.back();
    }
};

emplace_back()MyObject コンストラクターを呼び出し、コンストラクターに int パラメーターとして some_param を渡し、作成されたオブジェクトをリストの後ろに挿入する効果があります。コンストラクトの呼び出しは std::allocator 内から行われるため、そのフレンドシップが必要です。

于 2013-03-30T20:22:03.550 に答える
0

カスタム アロケータを作成し、それを 2 番目のパラメータとしてstd::vector<>. カスタム アロケータを MyObject のフレンドにします。カスタム アロケーターは特別なことをする必要はありません。唯一の目的は、フレンドであることによってプライベート コンストラクターにアクセスしながら、MyObjects を通常の方法で (たとえば、new を使用して) 割り当てることです。

于 2013-03-30T21:38:30.507 に答える