通常我們都將構(gòu)造函數(shù)的聲明置于public區(qū)段,假如我們將其放入private區(qū)段中會(huì)發(fā)生什么樣的后果?沒錯(cuò),我也知道這將會(huì)使構(gòu)造函數(shù)成為私有的,這意味著什么?
我們知道,當(dāng)我們?cè)诔绦蛑新暶饕粋€(gè)對(duì)象時(shí),編譯器為調(diào)用構(gòu)造函數(shù)(如果有的話),而這個(gè)調(diào)用將通常是外部的,也就是說它不屬于class對(duì)象本身的調(diào)用,假如構(gòu)造函數(shù)是私有的,由于在class外部不允許訪問私有成員,所以這將導(dǎo)致編譯出錯(cuò)。 你于是說:“哈哈。”我們制造了一個(gè)似乎無法產(chǎn)生對(duì)象的class.哦,當(dāng)然,對(duì)于class本身,我們還可以利用它的static公有成員,因?yàn)樗鼈儶?dú)立于class對(duì)象之外,我們不必產(chǎn)生對(duì)象也可以使用它們。嗯,看來我們還是為帶有私有構(gòu)造函數(shù)的類找到了一個(gè)存在的理由。不過我們不應(yīng)當(dāng)滿足于此,因?yàn)榭瓷先?yīng)當(dāng)還有發(fā)掘的余地。 首先我們來認(rèn)真看一下是不是真的無法創(chuàng)建出一個(gè)具有私有構(gòu)造函數(shù)的類對(duì)象。“呃,可能未必。”你現(xiàn)在也許會(huì)這樣說。這很好,讓我們?cè)賮砜纯礊槭裁?,沒錯(cuò),因?yàn)闃?gòu)造函數(shù)被class私有化了,所以我們要?jiǎng)?chuàng)建出對(duì)象,就必須能夠訪問到class的私有域;但這一點(diǎn)“我們”是做不到的,那么,誰能做得到呢?class的成員可以做得到;但在我們建構(gòu)出其對(duì)象之前,怎么能利用它的成員呢?噢,剛才我們剛剛提到了static公有成員,它是獨(dú)立于class對(duì)象而存在的,當(dāng)然,它也是公有的,“我們”可以訪問得到。假如在某個(gè)static函數(shù)中創(chuàng)建了該class的對(duì)象,并以引用或者指針的形式將其返回(不可以以值的形式返回,想想為什么),我們就獲得了這個(gè)對(duì)象的使用權(quán)。下面是例子: class WonderfulClass { public: static WonderfulClass* makeAnObject() { // 創(chuàng)建一個(gè)WonderfulClass對(duì)象并返回其指針 return (new WonderfulClass); // return ::WonderfulClass;//也可以這樣。 }
private: WonderfulClass() { } }; int main() { WonderfulClass *p = WonderfulClass::makeAnObject(); ... // 使用*p //如果要使用共有成員函數(shù)的話就用p->……就行 delete p; // Not neccesary here, but it's a good habit. return 0; } 嗯,這個(gè)例子使用了私有構(gòu)造函數(shù),但它運(yùn)行得很好:makeAnObject()作為WonderfulClass的靜態(tài)成員函數(shù),盡心盡責(zé)地為我們創(chuàng)建對(duì)象:由于要跨函數(shù)傳遞并且不能使用值傳遞方式,所以我們選擇在堆上創(chuàng)建對(duì)象,這樣即使makeAnObject()退出,對(duì)象也不會(huì)隨之蒸發(fā)掉,當(dāng)然,使用完之后你可不要忘了手工將它清除。 回到前面的思路:除了公有的static成員可以幫助我們?cè)L問私有域外,還有沒有其它可以利用的“東西”? 我們?cè)趐ublic段里聲明一個(gè)友元的函數(shù) friend WonderfulClass* Creat( ); 下面是友元函數(shù)的實(shí)現(xiàn): WonderfulClass* Creat( ) 我們知道沒有人會(huì)無聊到無緣無故把一個(gè)class設(shè)為私有,然后再寫一個(gè)和上面一模一樣的makeAnObject()來讓它的用戶體驗(yàn)一下奇特的感覺。我們也不太相信這只是由于C++的設(shè)計(jì)原因而導(dǎo)致的一個(gè)“順便的”“特殊的”“無用的”邊角功能。它應(yīng)當(dāng)是有實(shí)際用途的。提醒一下,到了JAVA中你會(huì)更容易明白很多靜態(tài)方法創(chuàng)建對(duì)象的原理!?。?BR> 嗯,例如,我們想實(shí)現(xiàn)這樣一個(gè)class:它至多只能存在一個(gè),或者指定數(shù)量個(gè)的對(duì)象(還記得標(biāo)準(zhǔn)輸入輸出流庫中那個(gè)獨(dú)一無二的cout嗎?),我們可以在class的私有域中添加一個(gè)static類型的計(jì)數(shù)器,它的初值置為0,然后再對(duì)makeAnObject()做點(diǎn)手腳:每次調(diào)用它時(shí)先檢查計(jì)數(shù)器的值是否已經(jīng)達(dá)到對(duì)象個(gè)數(shù)的上限值,如果是則產(chǎn)生錯(cuò)誤,否則才new出新的對(duì)象,同時(shí)將計(jì)數(shù)器的值增1.最后,為了避免值復(fù)制時(shí)產(chǎn)生新的對(duì)象副本,除了將構(gòu)造函數(shù)置為私有外,復(fù)制構(gòu)造函數(shù)也要特別聲明并置為私有。
噢,你一定想到了使用友元,完全正確??梢允褂迷擃惖挠言瘮?shù)或者友元類創(chuàng)建其對(duì)象。
{
return new WonderfulClass;
}
這樣我們也可達(dá)到同樣的目的;