2017-05-08 4 views
5

私のアプローチは、次のとおりです。どのように正しく生ポインタからstd :: unique_ptrに所有権を移動するには?

class SomeClass 
{ 
    std::vector<std::unique_ptr<MyObject>> myObjects; 
public: 
    void takeOwnership(MyObject *nowItsReallyMyObject) 
    { 
     myObjects.emplace_back(std::move(nowItsReallyMyObject)); 
    } 
}; 

アムは、私はすべてを正しく行うか、任意のより良い解決策があるのですか?

+0

'std :: move'は必要ありません。 – juanchopanza

+0

プリミティブ型(ポインタ)に 'std :: move'を呼び出す点はありません –

答えて

4

moveは冗長です。

自分を、私はこれを行うだろう:

void takeOwnership(std::unique_ptr<MyObject> nowItsReallyMyObject) 
{ 
    myObjects.emplace_back(std::move(nowItsReallyMyObject)); 
} 

私は限り「アウト」できるだけunique_ptr所有権のセマンティクスを移動したいと思うので。

私は、このユーティリティの機能を記述することがあります

template<class T> 
std::unique_ptr<T> wrap_in_unique(T* t) { 
    return std::unique_ptr<T>(t); 
} 

ので、発信者することができます:

foo.takeOwnership(wrap_in_unique(some_ptr)); 

が、さらに良いが、その後、限り、彼らは合理的にできる限りunique_ptrセマンティクスの境界を押し出すことができます。

私も行う可能性があります:発信者はより簡単だ自分T*unique_ptrに移行することができます

template<class T> 
std::unique_ptr<T> wrap_in_unique(T*&& t) { 
    auto* tmp = t; 
    t = 0; 
    return std::unique_ptr<T>(tmp); 
} 
template<class T> 
std::unique_ptr<T> wrap_in_unique(std::unique_ptr<T> t) { 
    return std::move(t); 
} 

を。 T* - >unique_ptr<T>のすべてがstd::moveにラップされ、ソースポインタがゼロになりました。

彼らは

struct I_am_legacy { 
    T* I_own_this = 0; 
    void GiveMyStuffTo(SomeClass& sc) { 
    sc.takeOwnership(wrap_in_unique(std::move(I_own_this))); 
    } 
}; 

を持っていたのであれば、コードを変換することができる。

struct I_am_legacy { 
    std::unique_ptr<T> I_own_this; 
    void GiveMyStuffTo(SomeClass& sc) { 
    sc.takeOwnership(wrap_in_unique(std::move(I_own_this))); 
    } 
}; 

、それはまだコンパイルし、同じように動作します。 (I_own_thisとのその他の対話は変更する必要がありますが、その一部はすでにunique_ptrと互換性があります)。

2

あなたがからunique_ptrを受け入れる必要があります。get-行く:

class SomeClass 
{ 
    std::vector<std::unique_ptr<MyObject>> myObjects; 
public: 
    // tells the world you 0wNz this object 
    void takeOwnership(std::unique_ptr<MyObject> myObject) 
    { 
     myObjects.push_back(std::move(myObject)); 
    } 
}; 

あなたはそれを明確にあなたが所有権を取得し、あなたはまた、生のポインタを使用しないように他のプログラマを支援しますこの方法です。

さらにリーディング:CppCoreGuidelines R.32

+0

ありがとう。しかし、私は[CppCoreGuidelines R.33](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#r33-take-a-unique_ptrwidget-parameter-to-express-that-a)にもっと興味があります。 -function-reseats-the-widget)である。関数が返ってから削除したくないので、refでmyObjectを取る必要があります。またVS2013はvalで渡そうとするとその関数が削除されていると言います。または私は間違っていますか? – Oliort

+0

@Oliortあなたのベクトルの中の 'std :: unique_ptr'に' std :: move() 'するので、関数が返ってから削除されません。 'std :: move'の後、パラメータのバージョンは' nullptr'になります – Galik

関連する問題