为矩阵类编写构造函数,解构函数和复制构造函数的方法

时间:2017-12-08 20:30:06

标签: c++ constructor copy-constructor

我正在尝试为矩阵类创建构造函数,析构函数和复制构造函数,我不确定我是否做得很好。

特别是,我不确定两件事:

  1. 析构函数是否也为复制构造函数中分配的内存释放内存?

  2. 关于第Mat[i][j]=other[i][j]行(请参阅下面的代码),我想知道是否应该写Mat[i][j]=other.Mat[i][j]代替?

  3. class Matrix
    {
    private:
        int rows;
        int cols;
        int **Mat;
    
    public:
        Matrix (const int &rows,const int &cols);
        Matrix (const Matrix &other);
        ~Matrix ();
    };
    
    Matrix::Matrix(const int &n_rows,const int &n_cols) //constructor of class Matrix
    {
        rows=n_rows; 
        cols=n_cols;
        Mat=new int* [cols];
    
        for(int i =0;i<rows;i++)
           Mat[i]=new int[cols];
    
        for(int i=0;i<rows;i++)
          for(int j=0;j<cols;j++)
            Mat[i][j]=0;            
    }
    
    Matrix::~Matrix () //destructor
    {
        for(int i =0;i<rows;i++)
            delete Mat[i];
    
        delete[] Mat;
    }
    
    Matrix::Matrix(const Matrix &other)  //copy constructor
    {
        cols=other.cols;
        rows=other.rows;
        Mat=new int* [other.rows];
    
        for(int i =0;i<other.rows;i++)
           Mat[i]=new int[other.cols];
    
        for(int i=0;i<other.rows;i++)
          for(int j=0;j<other.cols;j++)
                Mat[i][j]=other[i][j];
    }
    

3 个答案:

答案 0 :(得分:0)

构造函数是一个初始化特定类的对象实例的类操作。

对象创建涉及多个操作,例如:

  1. 分配内存以存储新对象的结构
  2. 正确初始化对象的属性。
  3. 复制构造函数是构造函数的一个特例,它将同一个类的实例作为输入参数。 - 它仍然是一个构造函数,执行上面提到的相同操作。

    析构函数是一个类操作,它负责在不再使用对象时完成对象的最终化。

    可以使用它定义的任何构造函数(普通构造函数或复制构造函数)构造对象。删除该对象时,应该在析构函数中释放由类分配的任何内存。

    希望这有帮助。

    至于你的代码相关问题;在调用复制构造函数时,您传递该类的现有对象实例。由于您没有实现任何运算符重载,因此您可以像访问#2中那样访问对象的属性。

    我不确定这是否完全回答了你的问题,但我希望它有所帮助。

答案 1 :(得分:0)

1)我认为解构器只删除属于的对象,因为复制构造的对象有自己的析构函数。

2)是的,Mat[i][j] = other.Mat[i][j]是正确的,但是如果你想让你的程序更快一点,那就尝试使用指针(我知道这不容易,但是当你习惯了它时那很难^^)

答案 2 :(得分:0)

  1. 是。对象仍然分配的任何内容都应该在析构函数中释放。分配给它的构造函数并不重要。

  2. 是的,您需要使用Mat[i][j]=other.Mat[i][j],特别是因为您尚未为您的班级定义任何operator[]

  3. 您还需要根据"Rule of Three"添加一个复制赋值运算符,它基本上表示:

      

    如果一个类需要用户定义的析构函数,用户定义的复制构造函数或用户定义的复制赋值运算符,那么它几乎肯定需要全部三个。

    试试这个:

    class Matrix
    {
    private:
        int rows;
        int cols;
        int **Mat;
    
    public:
        Matrix (int n_rows, int n_cols);
        Matrix (const Matrix &other);
        ~Matrix ();
    
        Matrix& operator=(const Matrix &rhs);
        // alternatively:
        // Matrix& operator=(Matrix rhs);
    };
    
    Matrix::Matrix(int n_rows, int n_cols)
    {
        rows = n _rows; 
        cols = n_cols;
    
        Mat = new int*[rows];
        for(int i = 0; i < rows; ++i)
        {
           Mat[i] = new int[cols];
           for(int j = 0; i < cols; ++j)
               Mat[i][j] = 0;
        }
    }
    
    Matrix::Matrix(const Matrix &other)
    {
        rows = other.rows;
        cols = other.cols;
    
        Mat = new int*[rows];    
        for(int i = 0; i < rows; ++i)
        {
            Mat[i] = new int[cols];
            for(int j = 0; j < cols; ++j)
                Mat[i][j] = other.Mat[i][j];
        }
    }
    
    Matrix::~Matrix()
    {
        for(int i = 0; i < rows; ++i)
            delete Mat[i];
        delete[] Mat;
    }
    
    Matrix& Matrix::operator=(const Matrix &rhs)
    {
        if (&rhs != this)
        {
            Matrix temp(rhs);
            std::swap(Mat, temp.Mat);
            std::swap(rows, temp.rows);
            std::swap(cols, temp.cols);
        }
    
        return *this;
    }
    
    // alternatively:
    /*
    Matrix& Matrix::operator=(Matrix rhs)
    {
        std::swap(Mat, rhs.Mat);
        std::swap(rows, rhs.rows);
        std::swap(cols, rhs.cols);
        return *this;
    }
    */
    

    更好的解决方案是不要直接使用new[] / delete[]。请改用std::vector,让它为您处理一切,从而让您的班级遵循&#34;零规则&#34;:

      

    具有自定义析构函数,复制/移动构造函数或复制/移动赋值运算符的类应专门处理所有权(从Single Responsibility Principle开始)。其他类不应该有自定义析构函数,复制/移动构造函数或复制/移动赋值运算符。

    class Matrix
    {
    private:
        std::vector<std:vector<int> > Mat;
    
    public:
        Matrix (int n_rows, int n_cols);
    };
    
    Matrix::Matrix(int n_rows, int n_cols)
    {
        Mat.resize(n_rows);
        for(int i = 0; i < n_rows; ++i)
           Mat[i].resize(n_cols, 0);
    
        /* alternatively:
        Mat.resize(n_rows, std::vector<int>(n_cols, 0));
        */
    }