2016-06-16 9 views
3
#include <iostream> 
#include <memory> 
using namespace std; 

int main() { 
    std::unique_ptr<int> ptrA = std::make_unique<int>(10); 

    ptrA = std::make_unique<int>(20); // case I 

    return 0; 
} 


#include <iostream> 
#include <memory> 
using namespace std; 

int main() { 
    std::unique_ptr<int> ptrA = std::make_unique<int>(10); 

    ptrA = nullptr;     // case II or ptrA.reset() 
    ptrA = std::make_unique<int>(20); 

    return 0; 
} 

多くの人がCase IIを使用しています。しかし、std::unique_ptrはスマートポインタですから、nullptrを割り当てるか、resetを呼び出して新しい値を再割り当てする必要があります。は新しい値を割り当てる前に `nullptr`を` std :: unique_ptr`に割り当てる必要がありますか?

私が間違っている場合は、私に修正してください。 nullptrに最初に割り当て

+0

は、なぜあなたはにはstd :: make_unique (10)を割り当てているのgcc 7.2および-O3でコードをhttps://godbolt.org/でのコンパイラのエクスプローラptrA = 20 - またはさらに短くすることができます:ptrA = std :: make_unique (20)を実行して、それを終了しますか?または、質問に文脈をもう少し与えるか? – stijn

+3

@stijnこのコードは実際のコードではなくアイデアを説明するためのものです。 – Slava

+0

@stijn、代入演算子を記述しているとしたら、そのメンバーの1つはunique_ptrです。 – q0987

答えて

4

だけやって、余分にだけでなく、誤解を招くです:unique_ptr::operator=が新しいものを取得する前にその所有のメモリを解放します割り当て前から

ptrA = std::make_unique<int>(20); 

で十分です。

+0

実際に 'std :: make_unique'を呼び出すのであれば、この方法で代入を使うのは意味があります。私は違いは 'std :: make_shared'にとってより重要だと思います。あなたがポインタに割り当てている場合、あなたは完全に正しいです。 – Guvante

+0

@ 101010ケースIを代わりに使用すると、潜在的な問題は何か。 – q0987

+0

@ q0987:一時的に 'std :: make_unique'呼び出しの結果を保持する一時的な一時ファイルを作成します(' ptrA'の中に移動されるため、ファイルは削除されますが保証はできません)。 – Guvante

7

新しい値を割り当てる前にnullptrを割り当てることは無意味です。

+4

無意味よりも悪い - 信号対雑音比が低下するため、有害です。 – SergeyA

1

私はリセットを呼び出すかnullptrを割り当てるのは無意味だと思っていましたが、これが原因でアセンブラのフットプリントが小さくなりました。

void test1() 
{ 
    auto test1 = std::make_unique<int>(5); 
    test1 = std::make_unique<int>(6); 
} 

驚くべきことに醜いバージョンよりも多くの命令を発生します:

void test2() 
{ 
    auto test1 = std::make_unique<int>(5); 
    test1 = nullptr; 
    test1 = std::make_unique<int>(6); 
} 
関連する問題