日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

effective c++条款11扩展——关于拷贝构造函数和赋值运算符

發(fā)布時(shí)間:2023/12/10 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 effective c++条款11扩展——关于拷贝构造函数和赋值运算符 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
effective c++條款11擴(kuò)展——關(guān)于拷貝構(gòu)造函數(shù)和賦值運(yùn)算符 作者:馮明德


重點(diǎn):包含動態(tài)分配成員的類 應(yīng)提供拷貝構(gòu)造函數(shù),并重載"="賦值操作符。

以下討論中將用到的例子:

class CExample { public: CExample(){pBuffer=NULL; nSize=0;} ~CExample(){delete pBuffer;} void Init(int n){ pBuffer=new char[n]; nSize=n;} private: char *pBuffer; //類的對象中包含指針,指向動態(tài)分配的內(nèi)存資源 int nSize; };

這個(gè)類的主要特點(diǎn)是包含指向其他資源的指針。

pBuffer指向堆中分配的一段內(nèi)存空間。

一、拷貝構(gòu)造函數(shù)

int main(int argc, char* argv[]) { CExample theObjone; theObjone.Init40); //現(xiàn)在需要另一個(gè)對象,需要將他初始化稱對象一的狀態(tài) CExample theObjtwo=theObjone; ... }

語句"CExample theObjtwo=theObjone;"用theObjone初始化theObjtwo。

其完成方式是內(nèi)存拷貝,復(fù)制所有成員的值。

完成后,theObjtwo.pBuffer==theObjone.pBuffer。

即它們將指向同樣的地方,指針雖然復(fù)制了,但所指向的空間并沒有復(fù)制,而是由兩個(gè)對象共用了。這樣不符合要求,對象之間不獨(dú)立了,并為空間的刪除帶來隱患。

所以需要采用必要的手段來避免此類情況。

回顧以下此語句的具體過程:首先建立對象theObjtwo,并調(diào)用其構(gòu)造函數(shù),然后成員被拷貝。

可以在構(gòu)造函數(shù)中添加操作來解決指針成員的問題。

所以C++語法中除了提供缺省形式的構(gòu)造函數(shù)外,還規(guī)范了另一種特殊的構(gòu)造函數(shù):拷貝構(gòu)造函數(shù),上面的語句中,如果類中定義了拷貝構(gòu)造函數(shù),這對象建立時(shí),調(diào)用的將是拷貝構(gòu)造函數(shù),在拷貝構(gòu)造函數(shù)中,可以根據(jù)傳入的變量,復(fù)制指針?biāo)赶虻馁Y源。

?

拷貝構(gòu)造函數(shù)的格式為:構(gòu)造函數(shù)名(對象的引用)

提供了拷貝構(gòu)造函數(shù)后的CExample類定義為:

class CExample { public: CExample(){pBuffer=NULL; nSize=0;} ~CExample(){delete pBuffer;} CExample(const CExample&); //拷貝構(gòu)造函數(shù) void Init(int n){ pBuffer=new char[n]; nSize=n;} private: char *pBuffer; //類的對象中包含指針,指向動態(tài)分配的內(nèi)存資源 int nSize; }; CExample::CExample(const CExample& RightSides) //拷貝構(gòu)造函數(shù)的定義 { nSize=RightSides.nSize; //復(fù)制常規(guī)成員 pBuffer=new char[nSize]; //復(fù)制指針指向的內(nèi)容 memcpy(pBuffer,RightSides.pBuffer,nSize*sizeof(char)); }

這樣,定義新對象,并用已有對象初始化新對象時(shí),CExample(const CExample& RightSides)將被調(diào)用,而已有對象用別名RightSides傳給構(gòu)造函數(shù),以用來作復(fù)制。

原則上,應(yīng)該為所有包含動態(tài)分配成員的類都提供拷貝構(gòu)造函數(shù)。

拷貝構(gòu)造函數(shù)的另一種調(diào)用。

當(dāng)對象直接作為參數(shù)傳給函數(shù)時(shí),函數(shù)將建立對象的臨時(shí)拷貝,這個(gè)拷貝過程也將調(diào)同拷貝構(gòu)造函數(shù)。

例如

BOOL testfunc(CExample obj); testfunc(theObjone); //對象直接作為參數(shù)。 BOOL testfunc(CExample obj) { //針對obj的操作實(shí)際上是針對復(fù)制后的臨時(shí)拷貝進(jìn)行的 }

還有一種情況,也是與臨時(shí)對象有關(guān)的

當(dāng)函數(shù)中的局部對象被被返回給函數(shù)調(diào)者時(shí),也將建立此局部對象的一個(gè)臨時(shí)拷貝,拷貝構(gòu)造函數(shù)也將被調(diào)用

?

CTest func() { CTest theTest; return theTest }

二、賦值符的重載

下面的代碼與上例相似

int main(int argc, char* argv[]) { CExample theObjone; theObjone.Init(40); CExample theObjthree; theObjthree.Init(60); //現(xiàn)在需要一個(gè)對象賦值操作,被賦值對象的原內(nèi)容被清除,并用右邊對象的內(nèi)容填充。 theObjthree=theObjone; return 0; }

也用到了"="號,但與"一、"中的例子并不同,"一、"的例子中,"="在對象聲明語句中,表示初始化。更多時(shí)候,這種初始化也可用括號表示。

例如 CExample theObjone(theObjtwo);

而本例子中,"="表示賦值操作。將對象theObjone的內(nèi)容復(fù)制到對象theObjthree;,這其中涉及到對象theObjthree原有內(nèi)容的丟棄,新內(nèi)容的復(fù)制。

但"="的缺省操作只是將成員變量的值相應(yīng)復(fù)制。舊的值被自然丟棄。

由于對象內(nèi)包含指針,將造成不良后果:指針的值被丟棄了,但指針指向的內(nèi)容并未釋放。指針的值被復(fù)制了,但指針?biāo)竷?nèi)容并未復(fù)制。

因此,包含動態(tài)分配成員的類除提供拷貝構(gòu)造函數(shù)外,還應(yīng)該考慮重載"="賦值操作符號。

類定義變?yōu)?

class CExample { ... CExample(const CExample&); //拷貝構(gòu)造函數(shù) CExample& operator = (const CExample&); //賦值符重載 ... }; //賦值操作符重載 CExample & CExample::operator = (const CExample& RightSides) { nSize=RightSides.nSize; //復(fù)制常規(guī)成員 char *temp=new char[nSize]; //復(fù)制指針指向的內(nèi)容 memcpy(temp,RightSides.pBuffer,nSize*sizeof(char)); delete []pBuffer; //刪除原指針指向內(nèi)容 (將刪除操作放在后面,避免X=X特殊情況下,內(nèi)容的丟失) pBuffer=temp; //建立新指向 return *this }

三、拷貝構(gòu)造函數(shù)使用賦值運(yùn)算符重載的代碼。

CExample::CExample(const CExample& RightSides) { pBuffer=NULL; *this=RightSides //調(diào)用重載后的"=" } posted on 2008-06-04 15:04 GXW 閱讀(...) 評論(...) 編輯 收藏

轉(zhuǎn)載于:https://www.cnblogs.com/Fancyboy2004/archive/2008/06/04/1213510.html

總結(jié)

以上是生活随笔為你收集整理的effective c++条款11扩展——关于拷贝构造函数和赋值运算符的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。