unique_ptr,移动构造函数,以及为什么总是尝试访问私有成员

时间:2013-02-01 15:28:57

标签: c++ c++11 copy-constructor unique-ptr move-constructor

我经常遇到这个问题,我相信移动构造函数是有序的,但我认为复制构造函数是问题而隐藏它似乎不起作用。

代码:

template <class T>
class LinkedList{
public:
    //
    LinkedList() {}
    LinkedList(const T &data);
    LinkedList(const T &data, const LinkedList &node);
    LinkedList(const LinkedList &object);
    LinkedList &operator=(const LinkedList &object);

    ~LinkedList() {}

    std::shared_ptr<LinkedList> push_back(const T& data);

private:
    T data;
    std::unique_ptr<LinkedList> link;

    std::unique_ptr<LinkedList> LinkFactory(const LinkedList &node);

    std::shared_ptr<LinkedList> CreateStartNode(const T &data);
    std::shared_ptr<LinkedList> CreateNode(const T &data, const LinkedList &node);
};

发生错误的特定行是:

LinkedList<T>::LinkedList(const LinkedList<T> &object) : data(object.data),  
link(std::move(object.link)) {}

我试图移动而不是复制复制构造函数中的链接无济于事。如果设计移动构造函数而不是合成,那会更好吗?

4 个答案:

答案 0 :(得分:5)

你不能移动一个常量对象,因为object被声明为const,object.link也是const。

这看起来像一个破碎的设计,因为通常该构造函数是副本构造函数,但你想尝试移动链接参数,这意味着你试图窃取它拥有的资源。你有一个LinkFactory方法,看起来你应该使用它,如果它做了名称所承诺的。

答案 1 :(得分:3)

采用lvalue引用的构造函数是复制构造函数,而不是移动构造函数。如果引用为const则无法修改现有对象,因此无法从中移动。 (你不应该删除const,因为这会给你一个奇怪的破坏性复制语义,并且移动语义被添加到语言中以避免这种怪异)。

由于unique_ptr成员,您的课程无法复制,因此您根本不应提供复制构造函数。你可以提供一个移动构造函数:

LinkedList<T>::LinkedList(LinkedList<T> && object) : 
    data(object.data), link(std::move(object.link)) {}

但是没有必要,因为隐式生成的移动构造函数会这样做(唯一的区别是数据被移动而不是复制)。

请记住,除非您明确地这样做,否则无法移动命名变量:

LinkedList<int> l1;
LinkedList<int> l2(l1);             // ERROR: tries to copy
LinkedList<int> l3(std::move(l1));  // OK: explicit move

答案 2 :(得分:0)

您要实现的语义是什么?在你的副本中 构造函数,被复制的对象是const(即 通常是正确的);试图移动任何东西都需要它 是非常数。这看起来像一个设计缺陷,但如果没有, 建立链接mutable可能就是答案。

答案 3 :(得分:0)

我将我的拷贝构造函数定义如下,并且使用unique_ptr我没有编译时或链接错误:

LinkedList<T>::LinkedList(const LinkedList &other){
data = other.data;
link(std::move(other.link.get()));
}

我感谢大家回答这个问题。