C++深拷貝與淺拷貝的區(qū)別及應(yīng)用
淺拷貝
只是對(duì)指針的拷貝,拷貝后兩個(gè)指針指向同一個(gè)內(nèi)存空間;
深拷貝
對(duì)指針指向的內(nèi)容進(jìn)行拷貝(重新分配內(nèi)存),經(jīng)深拷貝后的指針是指向不同地址的指針;
因此淺拷貝釋放內(nèi)存的時(shí)候很容易出現(xiàn)因?yàn)獒尫艃蓚€(gè)指針而內(nèi)存出錯(cuò)。
淺拷貝(釋放時(shí),因?yàn)槎啻吾尫懦鲥e(cuò))
只拷貝指針
//拷貝構(gòu)造函數(shù) Vector(const Vector<T>& v) :_start(nullptr) ,_finish(nullptr) ,_endOfStorage(nullptr) { _start=v._start; _finish=v._finish; _endOfStorage=v._endOfStorage; }
深拷貝
對(duì)資源進(jìn)行拷貝
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; }
寫一個(gè)Vector的類
template<class T> class Vector { typedef T* operator; typedef const T* const_iterator; iterator _start; iterator _finish; iterator _endOfStorage; public: //構(gòu)造函數(shù) Vector() :_start(nullptr) , _finish(nullptr) , _endOfStorage(nullptr) {} //析構(gòu)函數(shù) ~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; } };
可以用自己編輯器,把拷貝放進(jìn)去試試;
附:c++深拷貝與淺拷貝問題實(shí)例
淺拷貝:簡(jiǎn)單的賦值拷貝操作;
深拷貝:在堆區(qū)重新申請(qǐng)空間,再進(jìn)行拷貝操作;
問題:淺拷貝會(huì)帶來堆區(qū)內(nèi)存被重復(fù)釋放的問題,析構(gòu)函數(shù)被調(diào)用多次,導(dǎo)致程序運(yùn)行崩潰;
解決:通過深拷貝解決,在堆區(qū)重新申請(qǐng)內(nèi)存,各自釋放自己的內(nèi)存,避免重復(fù)釋放;
#include <iostream> using namespace std; class Person { public: Person() { cout << "Person的默認(rèn)構(gòu)造函數(shù)調(diào)用"<<endl; } Person(int age,int height) { m_Age = age; m_Height = new int(height);//堆區(qū)重新申請(qǐng)空間,進(jìn)行深拷貝,手動(dòng)申請(qǐng),手動(dòng)釋放; cout << "Person的有參函數(shù)調(diào)用" << endl; } int m_Age; int *m_Height; //自己實(shí)現(xiàn)拷貝構(gòu)造函數(shù),來避免編譯器的拷貝構(gòu)造函數(shù)造成淺拷貝問題; Person(const Person& p) { cout << "Person拷貝構(gòu)造函數(shù)" << endl; m_Age = p.m_Age; //m_Height = p.m_Height; 淺拷貝,編譯器默認(rèn)實(shí)現(xiàn)這行代碼; m_Height = new int(*p.m_Height);//深拷貝 } ~Person() { //析構(gòu)代碼,將堆區(qū)開辟數(shù)據(jù)做釋放操作 if (m_Height != NULL) { delete m_Height; m_Height = NULL; } cout << "Person的析構(gòu)函數(shù)調(diào)用" << endl; } }; void test01(){ Person p1(18,160); cout << "p1的年齡為:" << p1.m_Age<<"p1身高為:"<<*p1.m_Height<< endl; Person p2(p1);//編譯器默認(rèn)調(diào)用拷貝構(gòu)造函數(shù),進(jìn)行淺拷貝操作 cout << "p2的年齡為:" << p2.m_Age<< "p2身高為:"<<*p2.m_Height << endl; } int main(){ test01(); system("pause"); }
程序運(yùn)行結(jié)果:
總結(jié)
到此這篇關(guān)于C++深拷貝與淺拷貝區(qū)別及應(yīng)用的文章就介紹到這了,更多相關(guān)C++深拷貝與淺拷貝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解C++中的vector容器及用迭代器訪問vector的方法
使用迭代器iterator可以更方便地解引用和訪問成員,當(dāng)然也包括vector中的元素,本文就來詳解C++中的vector容器及用迭代器訪問vector的方法,需要的朋友可以參考下2016-05-05C++解決大數(shù)組棧內(nèi)存不夠問題的方法分析
這篇文章主要介紹了C++解決大數(shù)組棧內(nèi)存不夠問題的方法,結(jié)合實(shí)例形式對(duì)比分析了C++針對(duì)大數(shù)組棧內(nèi)存不足情況的常見解決方法及其優(yōu)缺點(diǎn),具有一定參考借鑒價(jià)值,需要的朋友可以參考下2018-05-05OpenCV輪廓檢測(cè)之boundingRect繪制矩形邊框
在進(jìn)行文本檢測(cè)時(shí),我們常常會(huì)用矩形邊框?qū)z測(cè)到的內(nèi)容框除。這篇文章主要為大家介紹的是OpenCV中能實(shí)現(xiàn)這一效果的函數(shù):boundingRect,感興趣的同學(xué)可以學(xué)習(xí)一下2021-12-12C語言使用普通循環(huán)方法和遞歸求斐波那契序列示例代碼
這篇文章主要介紹了C語言使用普通循環(huán)方法和遞歸求斐波那契序列示例代碼,大家參考使用吧2013-11-11實(shí)現(xiàn)posix消息隊(duì)列示例分享
這篇文章主要介紹了實(shí)現(xiàn)posix消息隊(duì)列示例,學(xué)習(xí)記錄鎖,線程互斥量,線程條件變量,內(nèi)存映射,信號(hào),線程的綜合應(yīng)用,需要的朋友可以參考下2014-02-02