为什么我们应该使用带有唯一指针的 std::move 语义?

4 c++ smart-pointers unique-ptr c++11 c++14

概念问题

假设我们有这样的简单示例:

 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;
}
Run Code Online (Sandbox Code Playgroud)

我们简单地知道std::unique_ptr与单一所有者拥有的资源概念绑定,并在多个所有者之间移动资源,而 shared_ptr 则具有相反的方面。如上面所示的示例,当您查看line-(1)line-(2)时 ,您会注意到违反了一些标准规则,因为 std::unique_ptr 没有定义复制构造函数和复制可赋值运算符,但在为了避免编译错误,我们必须使用std::move函数。

问题

为什么现代 C++ 编译器无法自动生成在line-(1)line-(2)中的唯一指针之间移动资源的指令?因为我们知道特意为此设计了独特的指针。为什么我们应该显式地使用 std::move 来指示机器移动资源的所有权?

std::unique_ptr 除了类模板之外什么都没有。我们知道,但是在第 1 行和第 -2 行中解决的情况存在问题,而编译器抱怨不允许复制 unique_pointers(已删除的函数)。为什么我们会出现此类错误,为什么 C++ 标准和编译器供应商不能重写这个概念吗?

特意设计的唯一指针是为了在传递其所有权的同时移动资源,当我们将其作为函数/构造函数参数传递或分配给另一个唯一指针时,从概念上讲,它应该以所有权移动资源,而不是其他任何东西,但为什么我们应该使用 std::move为了让编译器执行实际操作,为什么我们不能自由地调用 line-(1) 和 line-(2) 呢?(而智能编译器会为我们生成唯一指针之间的自动移动操作,除非存在const 或非常量引用传递)。

(抱歉,描述很长,英语也很蹩脚)谢谢。

The*_*ist 5

unique_ptr当超出范围时自动为您释放内存非常有用。uobj这就是它的工作。因此,由于它有 1 个必须释放的指针,因此它必须是unique 的,因此它的名称为:unique_ptr

当你做这样的事情时:

std::unique_ptr<int> uobjAlt = uobj;
Run Code Online (Sandbox Code Playgroud)

您正在发出复制操作,但是,您不应该复制指针,因为复制意味着两个对象uobjAltuobj都必须被释放,这将直接导致分段错误和崩溃。因此,通过使用std::move,您可以将所有权从一个对象转移到另一个对象。

如果您想有多个指向单个对象的指针,您应该考虑使用std::shared_ptr.