成员初始化列表中的 unique_ptr

新手上路,请多包涵

编辑: 我知道 unique_ptr 是不可复制的,只能移动。我不明白初始化列表会发生什么。

为什么成员初始化列表中的 unique_ptr 可以像在代码片段中一样工作?

 #include <memory>

class MyObject
{
public:
    MyObject() : ptr(new int) // this works.
    MyObject() : ptr(std::unique_ptr<int>(new int))
    // i found this in many examples. but why this also work?
    // i think this is using copy constructor as the bottom.
    {
    }

    MyObject(MyObject&& other) : ptr(std::move(other.ptr))
    {
    }

    MyObject& operator=(MyObject&& other)
    {
        ptr = std::move(other.ptr);
        return *this;
    }

private:
    std::unique_ptr<int> ptr;
};

int main() {
    MyObject o;
    std::unique_ptr<int> ptr (new int);
    // compile error, of course, since copy constructor is not allowed.
    // but what is happening with member initialization list in above?
    std::unique_ptr<int> ptr2(ptr);
}

原文由 pepero 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

在您的示例中, std::unique_ptr<int>(new int) 是一个右值,因此使用了 ptr 的移动构造函数。

The second time (in main ), std::unique_ptr<int> ptr2(ptr) doesn’t work because ptr is an lvalue, and cannot be moved directly (you can use std::move )。

原文由 Nelfeal 发布,翻译遵循 CC BY-SA 3.0 许可协议

这与 命名未命名 的对象有关。

当你这样做时:

 std::unique_ptr<int> ptr(new int);
//                   ^^^--- name is 'ptr'

但是当你这样做时:

 std::unique_ptr<int>(new int);
//                  ^--where is the name??

如果创建的对象没有名称,则称为 临时 对象或 r-value ,并且编译器对 r-values 的规则与对 命名对象l-values 的规则不同。

命名对象( _左值_)只能 复制 到另一个对象,但未命名对象( _右值_)可以 复制 或 _移动_。

在您的示例中,您使用 std::unique_ptr 。这些对象只能 _移动_,因为它们的复制语义已禁用。这就是为什么当您尝试 复制 一个时您的编译器会出错:

 std::unique_ptr<int> ptr (new int);
// compile error, copy constructor delete
std::unique_ptr<int> ptr2(ptr); // copy is disabled!!

这里 ptr 是一个 _命名对象_,所以它 _只能被复制_,但它的 复制语义 被禁用,所以整个操作是非法的。

但是,当您对这样的 未命名对象 执行类似操作时:

 MyObject() : ptr(std::unique_ptr<int>(new int))
                                     ^--- look no name!!!

然后编译器可以 复制 或 _移动_,它总是在尝试 复制 之前尝试 _移动_。

std::unique_ptr 完全是 _移动投诉_,所以编译器没有投诉。

原文由 Galik 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏