我知道,如果我有一个带有智能唯一指针的类,则无法将该类分配给另一个实例,因为不能复制唯一指针。我知道我可以使唯一指针成为共享指针,这样就可以解决问题。但是,如果我不想共享指针的所有权怎么办?是否可以创建一个赋值运算符来移动唯一指针并复制其他变量?
我了解到您可以使用std::move
来转让所有权。
#include <iostream>
#include <memory>
struct GraphStructure { };
class test {
int a;
std::vector<int> vector;
std::unique_ptr<GraphStructure> Graph_;
};
int main () {
test t1;
auto t2 = t1;
}
答案 0 :(得分:5)
类test
的默认 copy 构造函数被删除,因为成员(graph_
)无法复制(如果您仍然可以通过任何有意义的方式进行复制,例如通过创建图成员的 deep 副本,您必须在自己的副本构造函数上实现)。相反,默认的 move 构造函数仍然存在(std::unique_ptr
是可移动的)。因此,您可以执行以下操作:
test t1;
auto t2 = std::move(t1);
不过请注意,t1
然后不再不再持有任何对象(您移动了该对象,因此将其内容移动到了另一个对象一个),先前由t2
持有的对象将被销毁。如果这是有意义的状态,则由您决定...
侧面说明:我写的有关复制和移动构造函数的内容也适用于复制和移动分配...
答案 1 :(得分:3)
如果GraphStructure
是没有任何虚拟成员函数的类或结构,则很容易做到。我们可以编写一个函数来复制unique_ptr
内部的数据以创建新的GraphStructure
:
std::unique_ptr<GraphStructure> duplicate(std::unique_ptr<GraphStructure> const& ptr)
{
return std::make_unique<GraphStructure>(*ptr);
}
有了duplicate
之后,我们可以使用此类编写用于测试的副本构造函数:
class test {
std::unique_ptr<GraphStructure> ptr;
std::vector<int> values;
public:
// this can be defaulted
test() = default;
// we use duplicate to create a copy constructor
test(const test& source)
: ptr(duplicate(source.ptr)))
, values(source.values)
{}
// we can use the default move constructor
test(test&&) = default;
test& operator=(test const& source) {
ptr = duplicate(source.ptr);
values = source.values;
return *this;
}
// we can use the default move assignment operator
test& operator=(test&&) = default;
};
在这种情况下,向GraphStructure添加一个虚拟clone
方法,该方法将返回一个新的std::unique_ptr<GraphStructure>
:
class GraphStructure {
public:
// override this method in child classes
virtual std::unique_ptr<GraphStructure> clone() {
return std::make_unique<GraphStructure>(*this);
}
virtual ~GraphStructure() {}
};
然后,使用.clone()
代替duplicate