C 限制某個類所能產生的物件數量

2021-09-06 05:50:16 字數 4690 閱讀 5470

或者系統只提供16個可分發出去的檔案描述符,如何確保檔案描述符物件存在的數目不能超過16個。

在具體的應用過程中,我們可能需要限制某個類所產生的物件數量。

下面我們先從簡單的問題的開始。

1.如何允許建立零個物件?

例項化乙個物件時,將呼叫乙個建構函式,因而阻止建立某個類的物件,最容易的方法就是把該類的建構函式宣告在類的private域。**示例如下:

1

class

cantbeinstantiated

2;

2.如何允許建立乙個物件?

將類的建構函式宣告為private後,每個使用者都沒有權力建立物件,但實際應用的需求是我們需要建立乙個物件,因此我們需要選擇性地放鬆這個限制。

對於宣告為private的建構函式,我們可以引入友元函式或成員函式來進行訪問,並利用靜態成員變數來保證物件的唯一,具體實現**如下:

//

使用友元函式來訪問私有建構函式

namespace

printingstuff

;

printer&theprinter()

}using

printingstuff::theprinter;

theprinter().reset();

theprinter().submitjob(buffer);

1

//使用靜態成員函式來訪問私有建構函式

2class

printer3;

12 printer&printer::theprinter()

1317

18printer::theprinter().reset();

19 printer::theprinter().submitjob(buffer);

上述兩種實現思想是一致的,最終都是通過theprint()函式來完成客戶端與系統印表機互動訪問的需求。theprinter()函式的實現有兩點值得注意:

1)唯一的printer物件是位於函式裡的靜態成員而不是在類中的靜態成員。在類中的靜態物件有兩個缺點,乙個總是被構造(和釋放),即使不使用該物件;另乙個缺點是它的初始化時間不確定。

2)theprinter()函式沒有宣告為內聯函式,因為內聯意味編譯器用函式體代替對函式的每乙個呼叫,這樣會導致函式內的靜態物件在程式內被複製,可能會使程式的靜態物件的拷貝超過乙個。

上述兩種方法,都解決了允許建立乙個物件的問題,但無法解決允許建立多個物件的限制問題。

3.如何限制允許建立多個物件?

我們可以換一種思路,不利用友元函式或成員函式來作為建立物件的中介,而引入計數器簡單地計算物件的數目,一旦需要太多的物件,就丟擲異常。具體**實現如下:

1

class

printer

2; //

當需要的物件過多時,丟擲的異常類

5printer();

6 ~printer();

7...

8private:9

static

size_t numobjects;

10static

size_t maxobjects;

11 printer(const printer&rhs);

12};

1314 size_t printer::numobjects = 0

;15 size_t printer::maxobjects = 10;16

printer::printer()

1722

...23 ++numobjects;24}

25 printer::~printer()

26

此法的核心思想就是使用numobjects跟蹤printer物件存在的數量。當構造物件時,它的值就增加,釋放物件時,它的值就減少。如果試圖構造過多的物件,就會丟擲乙個toomanyobjects型別的異常。通過maxobjects設定可允許建立物件的最大數目。

以上兩種方法基本上可以滿足,限制物件數目的要求。但是具體應用中,仍會出現問題,上述兩種方法無法解決。如下面**所示:

1

class colorprinter:public

printer2;

56printer p;

7 colorprinter cp;

1

class

cpfmachine2;

9cpfmachine m1;

10 cpfmachine m2;

利用計數器的方法,上述**中,都將會產生多個printer物件,由printer被作為基類或者被包含於其他類中,導致其他物件的構造時,隱藏構造printer物件。這主要是計數器方法無法區分物件存在的三種不同環境:只有它們本身;作為其他派生類的基類;被嵌入在更大的物件中

利用theprinter()函式的方法,把printer物件的數量限制為乙個,這樣做的同時也會讓我們每一次執行程式時只能使用乙個printer物件。導致我們不能在程式的不同部分使用不同的printer物件。如下面偽**所示:

1

建立printer物件p1;

2使用p1;

3釋放p1;

4建立printer物件p2;

5使用p2;

6釋放p2;

7 ....

4.如何解決兩種方法存在的問題?

思路:將兩種方法結合,將建構函式宣告為private,限制其被繼承和被包含於其他的類,解決計數器的問題,並提供偽建構函式作為訪問物件的介面,並統計物件的個數,來解決限制構造多個物件和程式不同部分使用不同物件的問題。具體**實現如下:

1

class

printer2;

5//偽建構函式

6static printer*makeprinter();

7static printer* makeprinter(const printer&rhs);

8...

9private:10

static

size_t numobjects;

11static

const

size_t maxobjects;

12printer();

13 printer(const printer&rhs);

14};

1516 size_t printer::numobjects = 0;17

const size_t printer::maxobjects = 10;18

printer::printer()

1924

...25

}26 printer::printer(const printer&rhs)

2732

...33

}34 printer*printer:makeprinter()

3538 printer* printer::makeprinter(const printer&rhs)

3942 printer *p1 = printer::makeprinter();

到目前為止,對於限制物件數目的問題,應該是大功告成。但是仍不能滿足工程性上的應用,例如我們有大量像printer需要限制例項數量的類,就必須一遍又一遍地編寫一樣的**,每個類編寫一次。作為程式設計師,應該避免這種重複性的工作。

5.乙個具有物件計數功能的基類

針對重複性工作的問題,解決思路是:構造乙個具有例項計數功能的基類,讓像printer這樣的類從該基類繼承,利用派生類物件的構造,需要先構造基類物件的特點,通過隱藏的基類實現計數功能。具體實現如下:

1 template

2class

counted3;

6static

intobjectcount()710

protected:11

counted();

12 counted(const counted&rhs);

13 ~counted()

1417

private:18

static

intnumobjects;

19static

const

size_t maxobjects;

20void

init();

21};

2223 template

24 counted::counted()

2528

29 template30 counted::counted(const counted&)

3134

35 template

36void counted::init()

3742

43class printer::private counted44

;

c 限制某個class所能產生物件數量的方法

1.產生零個或乙個物件 將建構函式與拷貝建構函式宣告為私有成員,並宣告乙個友元函式,在友元函式中宣告乙個靜態成員,呼叫建構函式,並返回乙個靜態成員的引用。另一種方法就是設定乙個計數器,初始化為0.在建構函式中 1,在析構函式中 1,每次保證只有乙個物件。2.不同物件的構造狀態 上述第二種方法在繼承關...

M26 限制某個class所能產生的物件數量

1 每當產生乙個物件,必定呼叫構造方法。因此,禁止產生物件的做法就是,將所有的構造方法宣告為private。2 只有在類的內部才可以訪問private成員,有兩層含義 在類的內部可以訪問this的private成員,同時可以訪問同類物件的private成員。3 將構造方法宣告為private,只是限...

php 限制類的物件型別

事實上,採用哪種處理引數型別的策略,取決於任何潛在bug的嚴重程度。通常php會根據語境自動轉換大多數基本資料型別。因此,你需要在檢測型別 轉換型別和依賴良好清晰的文件 無論決定用哪一種,都應該提供文件 之間仔細權衡。無論你如何解決這類問題,都要認真思考一件事情 型別處理。php是一種弱型別的語言,...