拷貝構(gòu)造舌剂、拷貝賦值和析構(gòu)
c++中有Big Three三個(gè)特殊的函數(shù),他們就是拷貝構(gòu)造函數(shù)绒净,拷貝賦值函數(shù)和析構(gòu)函數(shù)。
那么什么被成為拷貝構(gòu)造函數(shù)呢偿衰?和構(gòu)造函數(shù)類似挂疆,拷貝構(gòu)造函數(shù)是用來在初始化類的實(shí)例時(shí)所使用的函數(shù),不過是以拷貝的方式下翎, 把一個(gè)已經(jīng)存在的類的對象賦值給另外一個(gè)對象缤言。拷貝構(gòu)造函數(shù)同構(gòu)造函數(shù)一樣视事,沒有返回值胆萧。因?yàn)槭峭粋€(gè)類的不同對象,所以在拷貝構(gòu)造函數(shù)中俐东,我們能夠直接訪問類中的私有成員變量跌穗。
如下這種做法是可以通過編譯的:
MyString::MyString(const MyString& rStr)
{
m_data = new char[strlen(rStr.m_data) + 1];
strcpy(m_data, rStr.m_data);
}
但是下面這種做法則不能通過編譯,原因就是這個(gè)拷貝構(gòu)造函數(shù)的傳入?yún)?shù)并不是同一個(gè)類的對象虏辫,而是另外一個(gè)類的對象蚌吸,所以它的私有成員變量是不可訪問的。
MyString::MyString(const OtherString& ostr)
{
m_data = new char[strlen(ostr.m_data) + 1];
strcpy(m_data, ostr.m_data);
}
拷貝賦值函數(shù)和賦值函數(shù)比較類似砌庄,需要通過重載操作符=來實(shí)現(xiàn)自己的拷貝賦值函數(shù)羹唠。在實(shí)現(xiàn)拷貝賦值函數(shù)的時(shí)候奕枢,需要注意的一點(diǎn)是:自引用的檢查。
如下是我實(shí)現(xiàn)的一個(gè)MyString的拷貝賦值函數(shù):
MyString& MyString::operator = (const MyString& rStr)
{
if (this == &rStr)//自引用檢查
return *this;
delete[] m_data;
m_data = new char[strlen(rStr.m_data) + 1];
strcpy(m_data, rStr.m_data);
return this;
}
最后是析構(gòu)函數(shù)肉迫。析構(gòu)函數(shù)是在類的對象生命周期結(jié)束的時(shí)候所調(diào)用的函數(shù)验辞。所以需要把類中通過Malloc或者new創(chuàng)建的內(nèi)存地址釋放掉,不然會(huì)導(dǎo)致內(nèi)存泄漏喊衫,當(dāng)工程項(xiàng)目比較大的時(shí)候跌造,甚至?xí)?dǎo)致程序的崩潰。使用free來釋放掉malloc函數(shù)分配的地址空間族购,delete來釋放new分配地址空間壳贪。侯老師有提到,其實(shí)new函數(shù)內(nèi)部就是先調(diào)用malloc函數(shù)給一個(gè)void指針分配一片內(nèi)存空間寝杖,然后將類型強(qiáng)制轉(zhuǎn)換為所要分配的類型违施,最后調(diào)用函數(shù)的構(gòu)造函數(shù)。delete函數(shù)原理也類似瑟幕。