当与运算符重载一起使用时,我对C ++移动语义感到困惑。
例如: (标题)
#pragma once
#include <vector>
namespace Mat {
using namespace std;
template <class T = double>
class Matrix {
public:
vector<vector<T>> &data;
size_t Rows;
size_t Cols;
// ctor
Matrix(size_t rows = 1, size_t cols = 1) :
data(*(new vector<vector<T>>(rows, vector<T>(cols)))) {
Rows = rows;
Cols = cols;
}
// copy assignment
Matrix &operator=(const Matrix &m) {
cout << "Copy =" << endl;
delete &data;
Rows = m.Rows;
Cols = m.Cols;
data = *(new vector<vector<T>>(m.data));
return *this;
}
// move assignment
Matrix &operator=(Matrix &&m) {
cout << "Move =" << endl;
Rows = m.Rows;
Cols = m.Cols;
data = m.data;
return *this;
}
// destructor
~Matrix() {
delete &data;
}
// addition
Matrix &operator+(const Matrix &right) {
const auto &left = *this;
auto &result = *(new Matrix<T>(left.Rows, left.Cols));
for (size_t r = 0; r < Rows; r++) {
for (size_t c = 0; c < Cols; c++) {
result.data[r][c] = left.data[r][c] + right.data[r][c];
}
}
return result;
}
};
}
(主/驱动器)
int _tmain(int argc, _TCHAR* argv []) {
Mat::Matrix<double> mat1(3,3);
Mat::Matrix<double> mat2(3, 3);
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(1, 6);
for (int r = 0; r < 3; r++) {
for (int c = 0; c < 3; c++) {
mat1.data[r][c] = distribution(generator);
mat2.data[r][c] = distribution(generator);
}
}
Mat::Matrix<double> mat3;
mat3 = mat1 + mat2;
}
当我执行此代码时。它表示“mat3 = mat1 + mat2”正在使用复制赋值运算符。我期望(并希望)它使用移动赋值运算符。我正在使用VS2013。
有人可以解释为什么会发生这种情况以及如何获得所需的移动语义吗? 感谢
答案 0 :(得分:1)
您的operator+
不仅会泄漏内存,还会通过引用返回Mat::Matrix
。因此,表达式mat1 + mat2
只能绑定到:
Matrix &operator=(const Matrix&);
您要做的是按值返回Matrix
。最后,我发现你到处都在使用new
。您不需要动态分配,尤其是std::vector
。
答案 1 :(得分:0)
在众多其他问题中,您的operator+()
返回非const
l值引用,而不是临时r值......因此它将绑定到{{1复制赋值运算符中的l值引用。