• C++动态申请二维数组与拷贝构造函数、等号重载


    一、C++动态申请二维数组

      在C++中不能直接动态申请二维数组,经过一番搜索,发现一种动态申请二维数组较好的方法。

      代码如下(MATRIX_TYPE为某一种类型,Lines、Columns分别为二维数组的行数、列数):

    MATRIX_TYPE** elem;
    //分配内存
    void Matrix::MemAlloc()
    {
        //C++二维矩阵动态申请空间
        elem = new MATRIX_TYPE*[Lines];
        elem[0] = new MATRIX_TYPE[Lines * Columns];
        for(int i = 1; i < Lines; i++)
            elem[i] = elem[i - 1] + Columns;
    }
    
    //释放内存
    void Matrix::MemFree()
    {
        //C++二维矩阵析构
        delete[] elem[0];
        delete[] elem;
    }

      这样可以直接读取和赋值:

    elem[i][j] = 0;

      这种方法申请二维数组的优点是内存连续,使用直接。

    二、C++拷贝构造函数、等号重载

      当使用一个对象通过另一个对象进行初始化、赋值或函数调用返回值时,C++会将原对象进行拷贝,再赋值给下一个对象。但是这会出现一个问题,就是当对象中包含动态成员时,C++无法将动态成员数据进行拷贝,即C++进行的拷贝仅仅是“浅拷贝”。

      当对象进行初始化时,C++会调用拷贝构造函数,当已初始化的对象进行赋值时,C++会调用等号重载。

      所以解决这一问题的一个办法是,重写拷贝构造函数并进行等号重载。形式如下:

    class Matrix
    {
    protected:
        int Lines;
        int Columns;
    public:
        MATRIX_TYPE** elem;
    
        //初始化
        Matrix();
        Matrix(int lines, int columns);
        ~Matrix();
    private:
        //分配内存
        void MemAlloc();
        void MemFree();
    public:
        //拷贝构造函数
        Matrix(const Matrix& m);
    
        //操作符重载
        //重载规范:双目友元函数重载,单目函数重载
        Matrix& operator =(const Matrix& m);                //由于构造函数中存在new,必须重载等号
        MATRIX_TYPE* operator [](int i);
        const MATRIX_TYPE* operator [](int i) const;
    };
    
    //初始化
    Matrix::Matrix()
    {
        Lines = 1;
        Columns = 1;
        MemAlloc();
    }
    
    Matrix::Matrix(int lines, int columns)
    {
        //由于在构造函数中存在new,故必须重写拷贝构造函数
        Lines = lines;
        Columns = columns;
    
        MemAlloc();
        memset(elem[0], 0, Lines * Columns * sizeof(MATRIX_TYPE));
    }
    
    Matrix::~Matrix()
    {
        MemFree();
    }
    
    //分配内存
    void Matrix::MemAlloc()
    {
        //C++二维矩阵动态申请空间
        elem = new MATRIX_TYPE*[Lines];
        elem[0] = new MATRIX_TYPE[Lines * Columns];
        for(int i = 1; i < Lines; i++)
            elem[i] = elem[i - 1] + Columns;
    }
    
    void Matrix::MemFree()
    {
        //C++二维矩阵析构
        delete[] elem[0];
        delete[] elem;
    }
    
    
    //拷贝构造函数
    Matrix::Matrix(const Matrix& m)
    {
        //由于在构造函数中存在new,故必须重写拷贝构造函数
        Lines = m.Lines;
        Columns = m.Columns;
    
        MemAlloc();
        memcpy(elem[0], m.elem[0], Lines * Columns * sizeof(MATRIX_TYPE));
    }
    
    //符号重载
    Matrix& Matrix::operator =(const Matrix& m)
    {
        //由于构造函数中存在new,必须重载等号
        if(this == &m) return *this;
        MemFree();
        Lines = m.Lines;
        Columns = m.Columns;
        MemAlloc();
        memcpy(elem[0], m[0], Lines * Columns * sizeof(MATRIX_TYPE));
        return *this;
    }
    
    MATRIX_TYPE* Matrix::operator [](int i)
    {
        return elem[i];
    }
    
    const MATRIX_TYPE* Matrix::operator [](int i) const
    {
        return elem[i];
    }
    Matrix m1 = Matrix(2, 2);
    Matrix m2 = m1;          //会调用拷贝构造函数
    Matrix m3 = Matrix(2, 2);
    m3 = m1;                 //会调用等号重载
  • 相关阅读:
    Java实现One-way traffic(单向交通)
    Java实现One-way traffic(单向交通)
    Java实现One-way traffic(单向交通)
    Java实现One-way traffic(单向交通)
    C#调用Delphi Dll返回字符串的示例(使用Move才能拷贝字符串)
    Delphi实现菜单项上出现提示
    WebBrowser中获得脚本中的变量值
    比较两个文件是否相同(比较两个流是否相等)
    WebBrowser执行脚本和调用外部方法
    c#之函数创建和闭包
  • 原文地址:https://www.cnblogs.com/Si-Mao/p/3965022.html
Copyright © 2020-2023  润新知