九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
拷貝構(gòu)造函數(shù)
(1)為什么要使用拷貝構(gòu)造函數(shù)?
當你把一個對象用值傳遞的方式傳參的話,會產(chǎn)生一個副本,或者把一個對象return傳出的時候也會產(chǎn)生副本。如果你沒有定義一個拷貝構(gòu)造函數(shù)的時候,副本是原對象的一個淺拷貝,又假如你的對象是一個包含指針的類對象,發(fā)生淺拷貝的時候只是將指針對應(yīng)的復(fù)制,并沒有開辟空間。1、值傳遞傳參,函數(shù)內(nèi)部對象的改變將導致外部的改變,因為副本和原對象的指針指向同一塊內(nèi)存。2、返回一個對象時,在函數(shù)作用域中的變量已經(jīng)失效,其傳出來的結(jié)果就可想而知了。這樣就會出現(xiàn)很多問題的。
(2)拷貝構(gòu)造函數(shù)的概念

拷貝構(gòu)造函數(shù),是一種特殊的構(gòu)造函數(shù),它由編譯器調(diào)用來完成一些基于同一類的其他對象的構(gòu)建及初始化。

其唯一的參數(shù)(對象的引用)是不可變的(const類型)。

此函數(shù)經(jīng)常用在函數(shù)調(diào)用時用戶定義類型的值傳遞及返回??截悩?gòu)造函數(shù)要調(diào)用基類的拷貝構(gòu)造函數(shù)和成員函數(shù)。如果可以的話,它將用常量方式調(diào)用,另外,也可以用非常量方式調(diào)用。
(3)什么時候用到拷貝構(gòu)造函數(shù)?

  在C++中,下面三種對象需要調(diào)用拷貝構(gòu)造函數(shù): 
  1) 一個對象以值傳遞的方式傳入函數(shù)體;
  2) 一個對象以值傳遞的方式從函數(shù)返回;
  3) 一個對象需要通過另外一個對象進行初始化;
     例如:CItem a;

       CItem b(a);     // 或CItem b; b =  a;

  如果在前兩種情況不使用拷貝構(gòu)造函數(shù)的時候,就會導致一個指針指向已經(jīng)被刪除的內(nèi)存空間。對于第三種情況來說,初始化和賦值的不同含義是構(gòu)造函數(shù)調(diào)用的原因。事實上,拷貝構(gòu)造函數(shù)是由普通構(gòu)造函數(shù)和賦值操作符共同實現(xiàn)的。描述拷貝構(gòu)造函數(shù)和賦值運算符的異同的參考資料有很多。
默認拷貝構(gòu)造函數(shù)的行為如下:
 默認的拷貝構(gòu)造函數(shù)執(zhí)行的順序與其他用戶定義的構(gòu)造函數(shù)相同,執(zhí)行先父類后子類的構(gòu)造.
 拷貝構(gòu)造函數(shù)對類中每一個數(shù)據(jù)成員執(zhí)行成員拷貝(memberwise Copy)的動作.
 a)如果數(shù)據(jù)成員為某一個類的實例,那么調(diào)用此類的拷貝構(gòu)造函數(shù).
 b)如果數(shù)據(jù)成員是一個數(shù)組,對數(shù)組的每一個執(zhí)行按位拷貝. 
 c)如果數(shù)據(jù)成員是一個數(shù)量,如int,double,那么調(diào)用系統(tǒng)內(nèi)建的賦值運算符對其進行賦值.
拷貝構(gòu)造函數(shù)是用一個存在的對象去構(gòu)造另一個不存在的對象   
  賦值函數(shù)是兩個對象都已存在,用一個對象的值去覆蓋另一個對象的值。   

*********************************************************
拷貝構(gòu)造函數(shù),經(jīng)常被稱作X(X&),是一種特殊的構(gòu)造函數(shù),他由編譯器調(diào)用來完成一些基于同一類的其他對象的構(gòu)件及初始化。它的唯一的一個參數(shù)(對象的引用)是不可變的(因為是const型的)。
*********************************************************

這個函數(shù)經(jīng)常用在函數(shù)調(diào)用期間于用戶定義類型的值傳遞及返回??截悩?gòu)造函數(shù)要調(diào)用基類的拷貝構(gòu)造函數(shù)和成員函數(shù)。如果可以的話,它將用常量方式調(diào)用,另外,也可以用非常量方式調(diào)用。
關(guān)于拷貝構(gòu)造函數(shù)和賦值運算符
作者:馮明德



重點:包含動態(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;
};



這個類的主要特點是包含指向其他資源的指針。 

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



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

int main(int argc, char* argv[])
{
CExample theObjone;
theObjone.Init40);

//現(xiàn)在需要另一個對象,需要將他初始化稱對象一的狀態(tài)
CExample theObjtwo=theObjone;
...
}


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

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

完成后,theObjtwo.pBuffer==theObjone.pBuffer。 
**********************************************************
即它們將指向同樣的地方,指針雖然復(fù)制了,但所指向的空間并沒有復(fù)制,而是由兩個對象共用了。這樣不符合要求,對象之間不獨立了,并為空間的刪除帶來隱患。 
*********************************************************
所以需要采用必要的手段來避免此類情況。 

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

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

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


拷貝構(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));
}



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


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


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


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

例如 
BOOL testfunc(CExample obj);

testfunc(theObjone); //對象直接作為參數(shù)。

BOOL testfunc(CExample obj)
{
//針對obj的操作實際上是針對復(fù)制后的臨時拷貝進行的
}



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

當函數(shù)中的局部對象被被返回給函數(shù)調(diào)者時,也將建立此局部對象的一個臨時拷貝,拷貝構(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)在需要一個對象賦值操作,被賦值對象的原內(nèi)容被清除,并用右邊對象的內(nèi)容填充。
theObjthree=theObjone;
return 0;
}


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

例如 CExample theObjone(theObjtwo); 

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

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

由于對象內(nèi)包含指針,將造成不良后果:指針的值被丟棄了,但指針指向的內(nèi)容并未釋放。指針的值被復(fù)制了,但指針所指內(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ù)使用賦值運算符重載的代碼。 

CExample::CExample(const CExample& RightSides)
{
pBuffer=NULL;
*this=RightSides  //調(diào)用重載后的"="
}



本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
數(shù)據(jù)結(jié)構(gòu)中的copy構(gòu)造函數(shù)和賦值重載函數(shù)-堅強的心-搜狐博客
深拷貝與淺拷貝
指針懸掛
C++拷貝構(gòu)造函數(shù)詳解(轉(zhuǎn))
C 拷貝構(gòu)造函數(shù)詳解
C++類構(gòu)造函數(shù)初始化列表
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服