T*中std :: unique_ptr <T>的构造函数背后的原因是什么?

Wal*_*ter 12 c++ explicit-constructor unique-ptr c++11

由于std::unique_ptr提供了一种避免内存泄漏并确保异常安全的便捷方法,因此传递它们而不是原始指针是明智的.因此,人们可能想要具有签名的(成员)函数

std::unique_ptr<some_type> foo(some data);
Run Code Online (Sandbox Code Playgroud)

不幸的是,在实现这样的功能时,不能简单地

std::unique_ptr<some_type> foo(some data)
{
  return { new some_type(data) };                  // error
}
Run Code Online (Sandbox Code Playgroud)

但必须改为

std::unique_ptr<some_type> foo(some data)
{
  return std::move( std::unique_ptr<some_type>( new some_type(data) ) );   // awkward
}
Run Code Online (Sandbox Code Playgroud)

因为构造函数unique_ptr::unique_ptr(pointer)explicit.这个构造函数背后的原因是explicit什么?

构造函数的一个动机explicit是防止意外的隐式类型转换.但是,由于unique_ptr不能通过价值传递,这应该不是一个真正的问题,是吗?

Hco*_*org 19

unique_ptr取得传递指针的所有权.取得所有权应该是明确的 - 你不希望一些指针'神奇'被一些类所拥有(和删除)(这是一个不赞成的问题std::auto_ptr).

例如:

void fun(std::unique_ptr<X> a) { .... }
X x;
fun(&x); // BOOM, deleting object on stack, fortunately it does not compile
fun(std::unique_ptr<X>(&x)); // compiles, but it's explicit and error is clearly visible
Run Code Online (Sandbox Code Playgroud)

请注意,声明中std::move不需return要这样做(特殊语言异常 - 作为return参数的局部变量可以被视为'移动').

另外 - 在C++ 14中你可以使用std::make_unique它来减少尴尬:

return std::make_unique<some_data>(some_data_argument1, arg2);
Run Code Online (Sandbox Code Playgroud)

(它也可以很容易地添加到C++ 11中 - 在这里阅读)


Yak*_*ont 5

采用独特ptr的参数不应该默默地拥有指针.

因此,ctor是明确的.

要返回,请尝试make_unique<foo>(?)代替{new foo(?)}.