编译器默认的拷贝构造函数,发生的是Memberwise Initialization(成员逐一初始化),类的成员变量被逐一复制。而默认赋值运算符,也是逐一复制成员变量。
一旦成员变量中,有程序员在heap开辟的空间(指针,new),使用默认拷贝构造函数就会引起浅拷贝和深拷贝的问题。
浅拷贝:将指针指向的地址复制给新初始化的对象对应的成员变量,两个类对象指向heap上的同一块内存。一旦其中一个对象释放那块内存,另一个对象的指针就会变成野指针,对其进行操作可能会产生非常严重的错误。
深拷贝:对指针类型的成员变量,在堆区中重新开辟一块内存,存储的地址不同但是值相同。避免了浅拷贝的问题。
#include <iostream>
using namespace std;
class Matrix{
public:
Matrix(int row, int col):_row(row),_col(col)
{
_pmat = new double[row * col];
}
Matrix(const Matrix& rhs):_row(rhs._row),_col(rhs._col)
{
int elem_cnt = _row*_col;
_pmat = new double[elem_cnt];
for(int ix=0;ix<elem_cnt;++ix)
_pmat[ix] = rhs._pmat[ix];
}
Matrix& operator=(const Matrix &rhs);
~Matrix(){
delete[] _pmat;
}
private:
int _row, _col;
double * _pmat;
};
Matrix& Matrix::operator=(const Matrix& rhs){
if(this != &rhs){
_row = rhs._row;
_col = rhs._col;
int elem_cnt = _row * _col;
delete[] _pmat;
_pmat = new double[elem_cnt];
for(int ix=0;ix<elem_cnt;++ix)
_pmat[ix] = rhs._pmat[ix];
}
return *this;
}
与拷贝构造函数的初始化功能不同,调用重载的赋值运算符时,类本身已经被初始化过了。所以需要先确定两个对象是否相同,然后删除原先开辟的空间。