我是 C++11 的新手,所以我仍然在努力解决它的概念。
这是我的问题:
我有一个矩阵类:
class matrix
{
private:
double** data;
size_t number_lines;
size_t number_columns;
size_t capacity_lines;
size_t capacity_columns;
public:
....
}
Run Code Online (Sandbox Code Playgroud)
我提供了一个复制构造函数,一个移动构造函数......
我重载了乘法运算符 *(double x) 以将矩阵元素乘以标量 x 并返回相乘后的矩阵。这是代码:
matrix matrix::operator*(double lambda)
{
double** aux_data = new double*[number_lines];
for (size_t i = 0; i < number_lines; i++)
{
aux_data[i] = new double[number_columns];
for (size_t j = 0; j < number_columns; j++)
aux_data[i][j] = lambda*data[i][j];
}
return matrix(aux_data, number_lines, number_columns);
}
Run Code Online (Sandbox Code Playgroud)
函数的返回是一个右值引用,因此它调用移动构造函数。这是移动构造函数的代码:
matrix::matrix(const matrix&& moved_copy)
{
if (this != &moved_copy)
{
number_columns = moved_copy.number_columns;
number_lines = moved_copy.number_lines;
data = moved_copy.data;
}
}
Run Code Online (Sandbox Code Playgroud)
这个移动构造函数的问题在于它执行的是浅拷贝而不是深拷贝(就像我猜的每个移动构造函数,否则这个移动构造函数的重点是什么)所以成员数据指向由moved_copy.data指向的对象,但是这个对象是运算符 *=() 函数的本地对象,所以当运算符超出范围时,对象消失了,我有一个悬空指针。所以我的问题是:我应该在移动构造函数中执行深层复制,还是有办法在不这样做的情况下解决这个问题?
谢谢你。
不,您不应该在移动构造函数中进行深拷贝。移动构造函数的全部意义在于获取某些复制成本高昂的资源的所有权。
在这种情况下,您的data指针的所有权可以从现有对象转移matrix到新构造的matrix对象。但这个想法是将所有权转移给新对象,而不是与新对象共享所有权。在这种情况下,这仅意味着设置moved_copy.data为nullptr,这样它data在销毁时就不会删除您。
matrix::matrix(matrix&& moved_copy)
{
number_columns = moved_copy.number_columns;
number_lines = moved_copy.number_lines;
data = moved_copy.data;
moved_copy.data = nullptr;
}
Run Code Online (Sandbox Code Playgroud)
请注意,我还删除了您的if防护:无法从自身构造对象,因此移动构造函数并不真正需要它(尽管它对于移动赋值运算符可能很有用)。
我也const从moved_copy. 移动构造函数需要修改被移动对象的状态以获取其资源的所有权,因此const不能使用。
编辑:实际上可以从自身构造一个对象,但这并不是您真正需要防范的。