C++空复制赋值运算符复制数据

c++ empty copy assignment operator copies data

我是 c++ 的新手,想编写一个小型矩阵库,它有一个基础 class Matrix,其中有一些新的矩阵类型,如 SparseMatrixDenseMatrixHashMatrix

我的基地class是这样的:


class Matrix {


protected:
    int m,n;


public:
    
    
    Matrix(int m_p, int n_p) : m(m_p), n(n_p){
        std::cout << "gen constr" << std::endl;
    }

    Matrix(Matrix& other) = delete;

    Matrix() = delete;
    
    virtual ~Matrix() {}


    int getM() const {
        return m;
    }

    int getN() const {
        return n;
    }

    virtual double& get(int m, int n) = 0;

    virtual double  get(int m, int n) const = 0;

    inline double& operator() (int m, int n){
        return get(m,n);
    }

    inline double  operator() (int m, int n) const{
        return get(m,n);
    }

    friend std::ostream &operator<<(std::ostream &os, Matrix &matrix) {

        using std::scientific;
        using std::fixed;

        os << std::fixed << std::setprecision(2) << scientific << std::setfill(' ');

        for(int i = 1; i <= matrix.getM(); i++){
            for(int j = 1; j <= matrix.getN(); j++){
                os << std::setw(10) << matrix.get(i,j)  << " ";
            }
            os << "\n";
        }
        return os;
    }
    
    
    Matrix& operator=(const Matrix& other) {
//        std::cout << "equality assign" << std::endl;
        return *this;
    }

};

如您所见,我已经覆盖了相等赋值运算符,它只是 returns 对象,实际上并不复制值。

我对 DenseMatrix 的第一个实现非常简单:

class DenseMatrix : public Matrix{


private:
    double* data;

public:

 
    DenseMatrix(int mP, int nP) : Matrix(mP, nP){
        std::cout << "gen constr base" << std::endl;
        this->data = new double[mP * nP]{0};
    }
        
    
    
    
    DenseMatrix() = delete;

    ~DenseMatrix() {
        delete this->data ;
    }

    double &get(int m, int n) {
        int index = m*getN()+n-(getN()+1);
        assert(index < (getN() * getM()) && index >= 0);
        return this->data [index];
    }

    double get(int m, int n)const {
        int index = m*getN()+n-(getN()+1);
        assert(index < (getN() * getM()) && index >= 0);
        return this->data [index];
    }
 
      
};

此外 main() 函数如下所示:

    DenseMatrix mat(3,3);
    for(int i = 1; i<= 3; i++){
        mat(i,i) = i;
    }
    
    DenseMatrix mat2(3,3);
    mat2 = mat;
    
    
    std::cout << mat << std::endl;
    std::cout << mat2 << std::endl;


>>>  1.00e+00   0.00e+00   0.00e+00 
>>>  0.00e+00   2.00e+00   0.00e+00 
>>>  0.00e+00   0.00e+00   3.00e+00 

>>>  1.00e+00   0.00e+00   0.00e+00 
>>>  0.00e+00   2.00e+00   0.00e+00 
>>>  0.00e+00   0.00e+00   3.00e+00 

如你所见,我首先创建了两个矩阵。我调整了第一个矩阵的值并将第二个矩阵的值保留为默认值 0。但是在调用相等赋值运算符之后,即使我实现的函数基本上没有影响矩阵的代码,第二个矩阵的内容也会发生变化。

我不明白这种行为,如果有人能简要解释一下这里发生的事情,我会很高兴。

非常感谢您的耐心等待和帮助:)

您尚未为 DenseMatrix 删除或定义 operator= 复制赋值运算符,因此编译器将为您合成一个。此函数将对数据成员进行成员明智的复制,在本例中为 double *data。由于指针将指向 matmat2 中的相同内容,因此打印出来时会看到相同的内容。

请注意,这可能不是您想要的。一个问题是您的 DenseMatrix 析构函数将 delete data 两次,可能导致段错误。

您没有为 DenseMatrix 定义赋值运算符。

隐式生成的赋值运算符对子对象进行赋值。基础子对象将使用 Matrix 的重载赋值运算符进行分配,因此存储在基础中的维度不会被修改 - 但您已将维度指定为相同,因此它们将被分配相同的无论如何值。