概念问题
假设我们有以下简单示例:
void foo(std::unique_ptr<int> ptr)
{
std::cout << *ptr.get() << std::endl;
}
int main()
{
std::unique_ptr<int> uobj = std::make_unique<int>(4);
foo(uobj ); // line-(1) Problem ,but Alternative -> foo(std::move(uobj ))
std::unique_ptr<int> uobjAlt = uobj; // line-(2) Problem ,but Alternative -> std::unique_ptr<int> uobjAlt = std::move(uobj);
return EXIT_SUCCESS;
}
我们知道,std::unique_ptr 的概念是资源只被单个所有者拥有,并可在多个所有者之间移动;而 shared_ptr 则具有相反的方面。
就像上面展示的例子一样,当您查看 line-(1) 和 line-(2) 时,您会注意到某些标准规则被违反了,因为 std::unique_ptr 没有定义复制构造函数和复制赋值运算符(已删除)。但为了避免编译错误,我们必须使用 std::move 函数。
问题
为什么现代 C++ 编译器不能自动生成指令来在 line-(1) 和 line-(2) 中在 unique pointers 之间移动资源?因为我们知道 unique pointer 的设计本意就是为了这个目的。为什么我们需要显式地使用 std::move 来指示机器移动资源的所有权?
虽然我们知道,std::unique_ptr 只是一个类模板,但是在 line -1 和 line -2 中的情况却存在问题,编译器会抱怨无法复制 unique pointers(已删除的函数)。为什么会出现这种错误?为什么 C++ 标准和编译器供应商不能覆盖这个概念呢?
Unique Pointer 的设计意图是为了在传递其所有权时移动资源,当我们将其作为函数/构造函数参数或分配给另一个 unique pointer 时,它应该只是概念上的所有权移动,而没有其他内容。但是为什么我们需要使用 std::move 来告诉编译器实际进行移动呢?为什么我们不能自由地调用 line-(1) 和 line-(2) 呢?(除非有 const 或非 const 引用 的传递)。
(对于冗长的描述和不太流利的英语表示抱歉)谢谢。
auto_ptr
的工作方式是这样的,而且非常糟糕。 - Dietrich Eppstd::string
没有隐式转换为const char*
,而是需要调用c_str()
函数,原因与这里相同:为了避免在内存管理时因疏忽而造成错误。 - Pete Becker