一、深拷貝和淺拷貝構(gòu)造函數(shù)總結(jié):
1、兩個(gè)特殊的構(gòu)造函數(shù):
(1)無(wú)參構(gòu)造函數(shù):
沒有參數(shù)的構(gòu)造函數(shù)
Class Test
{
public:
Test()
{
//這是一個(gè)無(wú)參構(gòu)造函數(shù)
}
};
當(dāng)類中沒有定義構(gòu)造函數(shù)時(shí),編譯器默認(rèn)提供一個(gè)無(wú)參構(gòu)造函數(shù),并且其函數(shù)體為空;換句話來說,就是我們?cè)陬愔?,不用我們程序猿自己寫,編譯就自動(dòng)提供了無(wú)參構(gòu)造函數(shù)(只是我們?nèi)庋劭床坏剑。?/p>
#include <iostream>
#include <string>
class Test{
//編譯器默認(rèn)給我們提供了一個(gè)無(wú)參構(gòu)造函數(shù),只是我們?nèi)庋劭床坏?br />
};
int main()
{
Test t;
return 0;
}
結(jié)果輸出(編譯時(shí)能夠通過的):
root@txp-virtual-machine:/home/txp# g++ test.cpp
root@txp-virtual-machine:/home/txp#
(2)拷貝構(gòu)造函數(shù):
參數(shù)為const class_name&的構(gòu)造函數(shù)
class Test{
public:
Test(const Test& p)
{
}
}
當(dāng)類中沒有定義拷貝構(gòu)造函數(shù)時(shí),編譯器默認(rèn)提供了一個(gè)拷貝構(gòu)造函數(shù),簡(jiǎn)單的進(jìn)行成員變量的值賦值
#include <iostream>
#include <string>
class Test{
private:
int i;
int j;
public:
Test(const Test& p)編譯器默認(rèn)提供這樣操作的
{
i = p.i;
j = p.j;
}
};
int main()
{
Test t;
return 0;
}
輸出結(jié)果(編譯可以通過):
root@txp-virtual-machine:/home/txp# g++ test.cpp
root@txp-virtual-machine:/home/txp#
(3)注意:
在寫程序的時(shí)候,定義的類對(duì)象初始化時(shí)看屬于哪種類型的:
Test t;//對(duì)應(yīng)無(wú)參構(gòu)造函數(shù)
Test t(1);//對(duì)應(yīng)有參構(gòu)造函數(shù)
Test t1;
Test t2=t1;//對(duì)應(yīng)拷貝構(gòu)造函數(shù)
比如下面我定義的類對(duì)象屬于無(wú)參構(gòu)造函數(shù)(當(dāng)然前提是你手寫了其他構(gòu)造函數(shù),雖然說編譯器會(huì)默認(rèn)提供,但是既然要手寫,那么三種構(gòu)造函數(shù)就在定義類對(duì)象的時(shí)候按需求來寫),如果只寫了有參數(shù)構(gòu)造函數(shù),那么編譯器就會(huì)報(bào)錯(cuò):
#include <iostream>
#include <string>
class Test{
private:
int i;
int j;
public:
Test(int a)
{
i = 9;
j=8;
}
Test(const Test& p)
{
i = p.i;
j = p.j;
}
};
int main()
{
Test t;
return 0;
}
輸出結(jié)果:
root@txp-virtual-machine:/home/txp# g++ test.cpp
test.cpp: In function ‘int main()’:
test.cpp:25:9: error: no matching function for call to ‘Test::Test()’
Test t;
^
test.cpp:25:9: note: candidates are:
test.cpp:15:3: note: Test::Test(const Test&)
Test(const Test& p)
^
test.cpp:15:3: note: candidate expects 1 argument, 0 provided
test.cpp:10:3: note: Test::Test(int)
Test(int a)
^
test.cpp:10:3: note: candidate expects 1 argument, 0 provided
4、拷貝構(gòu)造函數(shù)的意義:
(1)淺拷貝
拷貝后對(duì)象的物理狀態(tài)相同
(2)深拷貝
拷貝后對(duì)象的邏輯狀態(tài)相同
(3)編譯器提供的拷貝構(gòu)造函數(shù)只進(jìn)行淺拷貝
代碼版本一:
#include <stdio.h>
#include <string>
class Test{
private:
int i;
int j;
int *p;
public:
int getI()
{
return i;
}
int getJ()
{
return j;
}
int *getP()
{
return p;
}
Test(int a)
{
i = 2;
j = 3;
p = new int;
*p = a;
}
void free()
{
delete p;
}
};
int main()
{
Test t1(3);//Test t1 3;
Test t2 = t1;
printf("t1.i = %d, t1.j = %d, t1.p = %p", t1.getI(), t1.getJ(), t1.getP());
printf("t2.i = %d, t2.j = %d, t2.p = %p", t2.getI(), t2.getJ(), t2.getP());
t1.free();
t2.free();
return 0;
}
輸出結(jié)果:
root@txp-virtual-machine:/home/txp# g++ test.cpp
root@txp-virtual-machine:/home/txp# ./a.out
t1.i = 2, t1.j = 3, t1.p = 0x1528010
t2.i = 2, t2.j = 3, t2.p = 0x1528010
*** Error in `./a.out': double free or corruption (fasttop): 0x0000000001528010 ***
Aborted (core dumped)
注解:出現(xiàn)了段錯(cuò)誤,仔細(xì)分析,我們發(fā)現(xiàn)這里釋放了堆空間兩次(因?yàn)槲覀冞@里沒有調(diào)用拷貝構(gòu)造函數(shù),也就是自己去寫拷貝構(gòu)造函數(shù);所以這種情況是淺拷貝,不能釋放兩次堆空間):
代碼版本二(加上拷貝構(gòu)造函數(shù)):
#include <stdio.h>
#include <string>
class Test{
private:
int i;
int j;
int *p;
public:
int getI()
{
return i;
}
int getJ()
{
return j;
}
int *getP()
{
return p;
}
Test(int a)
{
i = 2;
j = 3;
p = new int;
*p = a;
}
Test(const Test& t)
{
i = t.i;
j = t.j;
p = new int;
*p = *t.p;
}
void free()
{
delete p;
}
};
int main()
{
Test t1(4);
Test t2 = t1;
printf("t1.i = %d, t1.j = %d, t1.p = %p", t1.getI(), t1.getJ(), t1.getP());
printf("t2.i = %d, t2.j = %d, t2.p = %p", t2.getI(), t2.getJ(), t2.getP());
t1.free();
t2.free();
return 0;
}
輸出結(jié)果:
root@txp-virtual-machine:/home/txp# g++ test.cpp
root@txp-virtual-machine:/home/txp# ./a.out
t1.i = 2, t1.j = 3, t1.p = 0xb0a010
t2.i = 2, t2.j = 3, t2.p = 0xb0a030
注解:從打印的p地址空間來看,就知釋放的兩個(gè)對(duì)象的堆空間不同,不再是指向同一堆空間了;同時(shí)我們發(fā)現(xiàn)淺拷貝只是簡(jiǎn)單數(shù)值上的進(jìn)行賦值而已;深拷貝不只是簡(jiǎn)單的值賦值,而是從內(nèi)存的角度來看,是操作不同的內(nèi)存。
5、什么時(shí)候需要進(jìn)行深拷貝?
(1)對(duì)象中有成員指代了系統(tǒng)中的資源
成員指向了動(dòng)態(tài)內(nèi)存空間
成員打開了外存中的文件
成員使用了系統(tǒng)中的網(wǎng)絡(luò)端口
注意:一般來說,自定義拷貝構(gòu)造函數(shù)(也就是我們自己手寫的),必然需要實(shí)現(xiàn)深拷貝!
二、總結(jié):
C++編譯器會(huì)默認(rèn)提供構(gòu)造函數(shù)
無(wú)參構(gòu)造函數(shù)用于定義對(duì)象的默認(rèn)初始化狀態(tài)
拷貝構(gòu)造函數(shù)在創(chuàng)建對(duì)象時(shí)拷貝對(duì)象的狀態(tài)
對(duì)象的拷貝有淺拷貝和深拷貝兩種方式。
好了,今天的分享就到這里,如果文章中有錯(cuò)誤或者不理解的地方,可以交流互動(dòng),一起進(jìn)步。我是txp,下期見!
-
可編程邏輯
+關(guān)注
關(guān)注
7文章
526瀏覽量
45412 -
C++
+關(guān)注
關(guān)注
22文章
2124瀏覽量
77147
發(fā)布評(píng)論請(qǐng)先 登錄
keil實(shí)現(xiàn)c與c++混合編程
內(nèi)存拷貝函數(shù) memcpy原理及實(shí)現(xiàn)
C語(yǔ)言與C++的區(qū)別及聯(lián)系
C與C++之間的聯(lián)系
C語(yǔ)言和C++之間的區(qū)別是什么
C++程序異常的處理機(jī)制
強(qiáng)實(shí)時(shí)運(yùn)動(dòng)控制內(nèi)核MotionRT750(六):us級(jí)高速交互之C++,為智能裝備提速
基于LockAI視覺識(shí)別模塊:C++目標(biāo)檢測(cè)
C++之拷貝構(gòu)造函數(shù)的淺copy及深copy
評(píng)論