雖然這篇文章的標題,看起來是有點找抽——既然一個類是空的,那不就是說里面啥也沒有嘛? 比如這樣:
class empty
{ };
上面定義了一個真的很空的空類,一對大括號里面除了空氣之外,真的什么都沒有!根據(jù)C++的語法,這樣的類是可以通過編譯的,并且可以跟別的小朋友一樣到處玩耍、奔跑和嬉鬧。look:
empty e1; // e1:“我很空虛!”
empty e2(e1); // e2:“我跟你一樣空虛!”
empty e3 = e1; // e3:“我也是!我也是!”
既然它能干這么多事情,說明這個“空”,是內(nèi)含玄機的。
仔細觀察上面三條語句,會發(fā)現(xiàn)如下事實:創(chuàng)建e1說明類empty中必然有無參構(gòu)造函數(shù),創(chuàng)建e2說明類中必然有復(fù)制構(gòu)造函數(shù),創(chuàng)建e3說明類中必然有賦值操作符函數(shù),當然我們還知道任何對象在釋放內(nèi)存時都會調(diào)用析構(gòu)函數(shù),因此毫無懸念類empty也必然有析構(gòu)函數(shù)。
綜上所述,你自認為內(nèi)部只有空氣的類empty,實際上是這個樣子的:
class empty
{
public:
empty(); // 無參構(gòu)造函數(shù)
empty(const empty &rh); // 復(fù)制構(gòu)造函數(shù)
~empty(); // 析構(gòu)函數(shù)
empty & operator=(const empty &rg); // 賦值操作符函數(shù)
};
注:如果類empty繼承了虛基類,那么析構(gòu)函數(shù)也將會自動被定義為虛函數(shù)。
原來!C++編譯器會為我們做這么多事情!
但,凡事皆有例外,以上那些不請自來的函數(shù)們,是不是任何時候都會出現(xiàn)呢?可不一定。請看精心設(shè)計的類node:
class node
{
public:
node(string &n, const int &a); // 顯式構(gòu)造函數(shù)
private:
string &name;
const int age;
};
node::node(string &n, const int &a)
: name(n), age(a)
{ }
首先,由于你提供了顯式的構(gòu)造函數(shù),因此系統(tǒng)將拒絕生成默認的無參構(gòu)造函數(shù)。
其次,注意到類node中包含引用成員name,以及非靜態(tài)的const型成員age,他們之中的任一個,都會導致系統(tǒng)拒絕生成默認的賦值操作符函數(shù)。
想象一下,此時如果定義兩個node的對象x1和x2,再讓它們之間相互賦值會怎樣?
string s1("aa"), s2("bb");
node x1(s1, 100), x2(s2, 200);
x1 = x2;
由于x1.name是引用,該引用指向了字符串s1(說白了就是x1.name就是s1的別名),那么 x1 = x2 會讓 x1.name 指向 s2 嗎? 從C++基本語法得知這不可能!因為引用一旦指定了關(guān)聯(lián)的目標就再也不能修改。那么, x1 = x2 會讓 x1.name指向的s1的值變?yōu)?bb"嗎? 這么一來,那其他跟x1無關(guān)的但使用了字符串s1的對象豈不是要平白無故地遭受牽連?
以上分析,針對類的非靜態(tài)const型成員age而言,是一模一樣的,因為age也不應(yīng)該通過類對象的賦值操作而發(fā)生改變。
因此,在上述情形下,默認的賦值操作符函數(shù)將不復(fù)存在,如果你非要為node提供賦值操作,你必須自己顯式地定義 operator=(),否則編譯器將會在上述代碼的 x1 = x2 這一行報錯。
事實上,還有一種情形會導致系統(tǒng)拒絕生成默認賦值操作符函數(shù),那就是當類node的基類定義了private的賦值操作符函數(shù)。這是因為,當要賦值node對象時,必須先調(diào)用基類的賦值操作符,而private的權(quán)限設(shè)定使這一想法立即破滅。
總而言之,以下情形發(fā)生時系統(tǒng)將拒絕生成默認賦值操作函數(shù):
類中含有引用成員
類中含有非靜態(tài)const型成員
類繼承自含有private賦值操作符函數(shù)的基類
詭異的是,即便在上述條件下,系統(tǒng)依然會贊同生成默認的拷貝構(gòu)造函數(shù),即以下代碼仍然是合法的:
string s1("aa");
node x1(s1, 100);
node x2(x1);
此時,x2和x1內(nèi)的兩個引用name都指向了s1,他們中的任意一個發(fā)生了變化都將對s1產(chǎn)生影響。消除這樣的副作用的辦法是,自己定義一個復(fù)制構(gòu)造函數(shù)來達成恰當?shù)倪壿嫛?/p> 識別下面二維碼,進入 微店●秘籍酷逛逛吧!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。