C++深拷貝與淺拷貝的區(qū)別及應用
淺拷貝
只是對指針的拷貝,拷貝后兩個指針指向同一個內(nèi)存空間;
深拷貝
對指針指向的內(nèi)容進行拷貝(重新分配內(nèi)存),經(jīng)深拷貝后的指針是指向不同地址的指針;
因此淺拷貝釋放內(nèi)存的時候很容易出現(xiàn)因為釋放兩個指針而內(nèi)存出錯。
淺拷貝(釋放時,因為多次釋放出錯)
只拷貝指針
//拷貝構(gòu)造函數(shù)
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:
//構(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;
}
};
可以用自己編輯器,把拷貝放進去試試;
附:c++深拷貝與淺拷貝問題實例
淺拷貝:簡單的賦值拷貝操作;
深拷貝:在堆區(qū)重新申請空間,再進行拷貝操作;
問題:淺拷貝會帶來堆區(qū)內(nèi)存被重復釋放的問題,析構(gòu)函數(shù)被調(diào)用多次,導致程序運行崩潰;
解決:通過深拷貝解決,在堆區(qū)重新申請內(nèi)存,各自釋放自己的內(nèi)存,避免重復釋放;
#include <iostream>
using namespace std;
class Person
{
public:
Person() {
cout << "Person的默認構(gòu)造函數(shù)調(diào)用"<<endl;
}
Person(int age,int height) {
m_Age = age;
m_Height = new int(height);//堆區(qū)重新申請空間,進行深拷貝,手動申請,手動釋放;
cout << "Person的有參函數(shù)調(diào)用" << endl;
}
int m_Age;
int *m_Height;
//自己實現(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; 淺拷貝,編譯器默認實現(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);//編譯器默認調(diào)用拷貝構(gòu)造函數(shù),進行淺拷貝操作
cout << "p2的年齡為:" << p2.m_Age<< "p2身高為:"<<*p2.m_Height << endl;
}
int main(){
test01();
system("pause");
}
程序運行結(jié)果:

總結(jié)
到此這篇關(guān)于C++深拷貝與淺拷貝區(qū)別及應用的文章就介紹到這了,更多相關(guān)C++深拷貝與淺拷貝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解C++中的vector容器及用迭代器訪問vector的方法
使用迭代器iterator可以更方便地解引用和訪問成員,當然也包括vector中的元素,本文就來詳解C++中的vector容器及用迭代器訪問vector的方法,需要的朋友可以參考下2016-05-05
C++解決大數(shù)組棧內(nèi)存不夠問題的方法分析
這篇文章主要介紹了C++解決大數(shù)組棧內(nèi)存不夠問題的方法,結(jié)合實例形式對比分析了C++針對大數(shù)組棧內(nèi)存不足情況的常見解決方法及其優(yōu)缺點,具有一定參考借鑒價值,需要的朋友可以參考下2018-05-05
C語言使用普通循環(huán)方法和遞歸求斐波那契序列示例代碼
這篇文章主要介紹了C語言使用普通循環(huán)方法和遞歸求斐波那契序列示例代碼,大家參考使用吧2013-11-11

