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;                 //会调用等号重载

 

posted @ 2014-09-10 19:20  死猫  阅读(1672)  评论(0编辑  收藏  举报