1

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

编码:

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

4 回答 4

5

您不能移动常量对象,并且由于object声明为 const,object.link因此也是 const。

这看起来像是一个损坏的设计,因为通常该构造函数是一个复制构造函数,但是您试图链接移出参数,这意味着您试图窃取它拥有的资源。您有一个 LinkFactory 方法,看起来您应该使用该方法,如果它符合名称的承诺。

于 2013-02-01T15:35:48.507 回答
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
于 2013-02-01T15:38:14.840 回答
0

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

于 2013-02-01T15:38:33.133 回答
0

我按如下方式定义了我的复制构造函数,并且使用 unique_ptr 没有编译时或链接错误:

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

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

于 2013-02-01T19:21:13.847 回答