拷貝構造函數和賦值運算符重載

編譯器默認的拷貝構造函數,發生的是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;
}
與拷貝構造函數的初始化功能不同,調用重載的賦值運算符時,類本身已經被初始化過了。所以需要先確定兩個對象是否相同,然後刪除原先開闢的空間。	
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章