拷貝構造函數與深淺拷貝
當我們通過普通的構造函數構造出一個對象之後,用這個對象去初始化另一個新建的對象,如這種:
test a(1);
test b = a 或者test b(a) 這兩種
還有這種 test & gettestObject()
則需要調用拷貝構造函數,如果我們沒有顯式的聲明一個拷貝構造函數,系統會生成一個默認的,自定義拷貝構造函數是一種良好的編程習慣
#include "stdafx.h"
#include <stdio.h>
#include<iostream>
class people
{
public:
people(char* name)
{
strcpy(cname,name);
pname = new char[strlen(cname)+1];
if(name != NULL)
{
strcpy(pname,cname);
}
}
void show()
{
std::cout<<"my name is:"<<pname<<std::endl;
}
/*
people(people& p1)
{
std::cout<<"深拷貝"<<std::endl;
strcpy(cname,p1.cname);
pname = new char[strlen(cname)+1];
if(cname != NULL)
{
strcpy(pname,cname);
}
}
*/
~people()
{
if(pname != NULL)
{
delete[] pname;
pname = NULL;
}
}
private:
char cname[20];
char * pname;
};
void main()
{
people a("lcl");
people b = a;
b.show();
system("pause");
}
堆空間看成一種資源,系統默認的拷貝函數屬於淺拷貝,去掉註釋的部分,我們看淺拷貝後運行起來a,b的地址情況:
只是簡單的復制,a、b對象內成員指針指向同一片空間
那在析構的時候,先析構a,那b中的pname就會變成野指針,也可以這麽想,兩個析構函數釋放同一塊堆內存會導致程序錯誤
深拷貝,加上自定義的拷貝函數後,就變成了深拷貝,復制了一份相同的資源,放在不同的地方,去掉上圖註釋部分,運行得到如下:
這就完成了深拷貝的過程。
混時長ing.........
拷貝構造函數與深淺拷貝