六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

對于拷貝構造函數與賦值運算符

[摘要]作者:馮明德重點:包含動態分配成員的類 應提供拷貝構造函數,并重載"="賦值操作符。 以下討論中將用到的例子: class CExamplepublic: CExample()pBuffer=NULL; nSize=0; ~CExample()delete pBuffer; v...

作者:馮明德

重點:包含動態分配成員的類 應提供拷貝構造函數,并重載"="賦值操作符。


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

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


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

pBuffer指向堆中分配的一段內存空間。


一、拷貝構造函數

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

//現在需要另一個對象,需要將他初始化稱對象一的狀態
CExample theObjtwo=theObjone;
...
}


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

其完成方式是內存拷貝,復制所有成員的值。

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

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

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

回顧以下此語句的具體過程:首先建立對象theObjtwo,并調用其構造函數,然后成員被拷貝。

可以在構造函數中添加操作來解決指針成員的問題。

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


拷貝構造函數的格式為:構造函數名(對象的引用)

提供了拷貝構造函數后的CExample類定義為:

class CExample
{
public:
CExample(){pBuffer=NULL; nSize=0;}
~CExample(){delete pBuffer;}
CExample(const CExample&); //拷貝構造函數
void Init(int n){ pBuffer=new char[n]; nSize=n;}
private:
char *pBuffer; //類的對象中包含指針,指向動態分配的內存資源
int nSize;
};

CExample::CExample(const CExample& RightSides) //拷貝構造函數的定義
{
nSize=RightSides.nSize; //復制常規成員
pBuffer=new char[nSize]; //復制指針指向的內容
memcpy(pBuffer,RightSides.pBuffer,nSize*sizeof(char));
}


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


原則上,應該為所有包含動態分配成員的類都提供拷貝構造函數。


拷貝構造函數的另一種調用。


當對象直接作為參數傳給函數時,函數將建立對象的臨時拷貝,這個拷貝過程也將調同拷貝構造函數。

例如

BOOL testfunc(CExample obj);

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

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


還有一種情況,也是與臨時對象有關的

當函數中的局部對象被被返回給函數調者時,也將建立此局部對象的一個臨時拷貝,拷貝構造函數也將被調用


CTest func()
{
CTest theTest;
return theTest
}


二、賦值符的重載

下面的代碼與上例相似

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

CExample theObjthree;
theObjthree.Init(60);

//現在需要一個對象賦值操作,被賦值對象的原內容被清除,并用右邊對象的內容填充。
theObjthree=theObjone;
return 0;
}


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

例如 CExample theObjone(theObjtwo);

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

但"="的缺省操作只是將成員變量的值相應復制。舊的值被自然丟棄。

由于對象內包含指針,將造成不良后果:指針的值被丟棄了,但指針指向的內容并未釋放。指針的值被復制了,但指針所指內容并未復制。


因此,包含動態分配成員的類除提供拷貝構造函數外,還應該考慮重載"="賦值操作符號。

類定義變為:

class CExample
{
...
CExample(const CExample&); //拷貝構造函數
CExample& operator = (const CExample&); //賦值符重載
...
};


//賦值操作符重載
CExample & CExample::operator = (const CExample& RightSides)
{
nSize=RightSides.nSize; //復制常規成員
char *temp=new char[nSize]; //復制指針指向的內容
memcpy(temp,RightSides.pBuffer,nSize*sizeof(char));

delete []pBuffer; //刪除原指針指向內容  (將刪除操作放在后面,避免X=X特殊情況下,內容的丟失)
pBuffer=temp;   //建立新指向
return *this
}

三、拷貝構造函數使用賦值運算符重載的代碼。

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



主站蜘蛛池模板: 日韩黄色免费观看 | 亚洲综合激情丁香六月 | 日韩看片网站 | 欧美一级做a爰片免费 | 亚洲图欧美 | 欧美性插视频 | 亚洲天堂一区二区 | 午夜影视在线免费观看 | 日日摸日日 | 青草青在线免费视频 | 亚洲欧美精品一区二区 | 一级黄色在线视频 | 天堂网日本 | 亚洲成a人片在线观看中文!!! | 人人狠狠综合久久亚洲 | 日本一区二区高清免费不卡 | 日韩免费高清视频 | 亚洲激情视频在线播放 | 婷婷操 | 欧洲精品视频完整版在线 | 天天躁夜夜躁很很躁 | 午夜激情影院 | 夭天干天天做天天免费看 | 青青草视频在线观看 | 色综合天天综合网国产成人 | 午夜欧美激情 | 小说区图片区综合久久亚洲 | 日本韩国在线播放 | 视频大全在线观看免费 | 日本高清视频在线的 | 在线观看h视频 | 日韩成人在线免费视频 | 欧美亚洲日本国产 | 色噜噜噜| 日本后进式猛烈xx00动态图 | 日日爱影视 | 综合久久久久6亚洲综合 | 人人干狠狠操 | 日日夜夜精品免费视频 | 午夜精品视频在线观看 | 日本亚欧乱色视频在线系列 |