对带有运算符重载的移动语义感到困惑

Confused about move semantics w/ operator overloading

本文关键字:语义 移动 运算符 重载      更新时间:2023-10-16

我对与运算符重载一起使用时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。

有人可以解释为什么会发生这种情况以及如何获得所需的移动语义吗?谢谢

您的operator+不仅会泄漏内存,还会通过引用返回Mat::Matrix。因此,表达式mat1 + mat2只能绑定到:

Matrix &operator=(const Matrix&);

您要做的是按值返回Matrix。最后,我看到你到处都在使用new。您不需要动态分配,尤其是使用 std::vector .

在一堆其他问题中,您的operator+()返回的是非const l 值引用,而不是临时 r 值......因此,它将绑定到复制赋值运算符中的const L 值引用。