この種の質問はここではあまり歓迎されないことはわかっていますが、質問する必要があります。
と書いた方が自然でしょう。
std::unique_ptr<int> p = new int(5);
それ以外の
std::unique_ptr<int> p(new int(5));
または他のより詳細な方法。
これを書くことを許可された場合:
std::unique_ptr<int> p = new int(5);
次に、これらを書くことも許可されます。
void Func1(std::unique_ptr<int> p);
Func1(new int(5));
std::unique_ptr<int> Func2() {return new int(5);}
または、はるかに危険です:
void Func1(std::unique_ptr<int> p);
int *pInt = new int(5);
Func1(pInt); //You no longer own the pointer anymore.
delete pInt; //You're now deleting a pointer you don't own.
明らかな理由から、これは受け入れられません。ネイキッド ポインターから一意のポインターへの暗黙的な変換は必要ありません。を作成したい場合はunique_ptr
、それについて明示する必要があります。Func1(std::unique_ptr<int>(pInt));
これで、所有権を自分から関数に移していることを誰もが見ることができます。
また、operator=
これを機能させるものではありません。コピー初期化構文が機能しなくなるのはexplicit
、の単一引数コンストラクターにあります。unique_ptr
あなたが言及しているのは、生のポインターunique_ptr<T>
を取るコンストラクターがexplicitであるという事実です。これは意図的なものです。一意のポインターは所有権を取得しますが、これは暗黙的に行われるべきではありません。ユーザーは、所有権がいつ作成、譲渡、終了されるかを常に明示的に認識している必要があります。T
より厳格な世界では、生のポインターをまったく使用せず、代わりに所有オブジェクトの直接作成のみを許可するをunique_ptr
想像できます。
auto p = std::unique_ptr<T>::make(arg1, arg2, arg3);
// Calls "new T(arg1, arg2, arg3)".
// Not real code.