C++深拷貝與淺拷貝的區別及應用

淺拷貝

隻是對指針的拷貝,拷貝後兩個指針指向同一個內存空間;

深拷貝

對指針指向的內容進行拷貝(重新分配內存),經深拷貝後的指針是指向不同地址的指針;

因此淺拷貝釋放內存的時候很容易出現因為釋放兩個指針而內存出錯。

淺拷貝(釋放時,因為多次釋放出錯)

隻拷貝指針

	//拷貝構造函數
	Vector(const Vector<T>& v)
		:_start(nullptr)
		,_finish(nullptr)
		,_endOfStorage(nullptr)
	{
		_start=v._start;
		_finish=v._finish;
		_endOfStorage=v._endOfStorage;
	}

深拷貝

對資源進行拷貝

 Vector(const Vector<T>& v)
	
		:_start(nullptr)
		, _finish(nullptr)
		, _endOfStorage(nullptr)
	{
		size_t n = v.capacity();
		_start = new T[n];
		for (size_t i = 0; i < v.size(); ++i)
		{
			_start[i] = v[i];
		}
		_finish = _start + v.size();
		_endOfStorage = _start + n;
	}

寫一個Vector的類

 template<class T>
class Vector
{
typedef T* operator;
typedef const T* const_iterator;
	iterator _start;
	iterator _finish;
	iterator _endOfStorage;
	
 public:
//構造函數
 Vector()
		:_start(nullptr)
		, _finish(nullptr)
		, _endOfStorage(nullptr)
	{}

	//析構函數
	~Vector()
	{
		if(_start)
		{
			delete[] _start;
			_star=_finish=_endOfStorage=nullptr;
		}
	}
T& operator[](size_t pos)
	{
		if (pos >= 0 && pos < size())
			return _start[pos];
	}
size_t size() const
{
	return _finish - _start;
}
 
size_t capacity() const
{
	return _endOfStorage - _start;
}


};

可以用自己編輯器,把拷貝放進去試試;

附:c++深拷貝與淺拷貝問題實例

淺拷貝:簡單的賦值拷貝操作;

深拷貝:在堆區重新申請空間,再進行拷貝操作;

問題:淺拷貝會帶來堆區內存被重復釋放的問題,析構函數被調用多次,導致程序運行崩潰;

解決:通過深拷貝解決,在堆區重新申請內存,各自釋放自己的內存,避免重復釋放;

#include <iostream>

using namespace std;

class Person
{
public:
    Person() {
        cout << "Person的默認構造函數調用"<<endl;
    }
    Person(int age,int height) {
        m_Age = age;
        m_Height = new int(height);//堆區重新申請空間,進行深拷貝,手動申請,手動釋放;
        cout << "Person的有參函數調用" << endl;
    }
    int m_Age;
    int *m_Height;

    //自己實現拷貝構造函數,來避免編譯器的拷貝構造函數造成淺拷貝問題;
    Person(const Person& p) {
        cout << "Person拷貝構造函數" << endl;
        m_Age = p.m_Age;
        //m_Height = p.m_Height; 淺拷貝,編譯器默認實現這行代碼;
        m_Height = new int(*p.m_Height);//深拷貝
    }

    ~Person() {
        //析構代碼,將堆區開辟數據做釋放操作
        if (m_Height != NULL) {
            delete m_Height;
            m_Height = NULL;
        }
        cout << "Person的析構函數調用" << endl;
    }
};

void test01(){
    Person p1(18,160);
    cout << "p1的年齡為:" << p1.m_Age<<"p1身高為:"<<*p1.m_Height<< endl;
    Person p2(p1);//編譯器默認調用拷貝構造函數,進行淺拷貝操作
    cout << "p2的年齡為:" << p2.m_Age<< "p2身高為:"<<*p2.m_Height << endl;
}

int main(){
    test01();
    system("pause");
}

程序運行結果:

總結

到此這篇關於C++深拷貝與淺拷貝區別及應用的文章就介紹到這瞭,更多相關C++深拷貝與淺拷貝內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀:

    None Found