我经常遇到这个问题,我相信移动构造函数是有序的,但我认为复制构造函数是问题而隐藏它似乎不起作用。
代码:
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)) {}
我试图移动而不是复制复制构造函数中的链接无济于事。如果设计移动构造函数而不是合成,那会更好吗?
答案 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()));
}
我感谢大家回答这个问题。