国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

C++對象計數(shù)

2019-11-17 05:20:43
字體:
供稿:網(wǎng)友
文本要害字:程序設(shè)計/C++/技巧   本文目的是實現(xiàn)一個實用的對C++類計數(shù)的類,同時在實現(xiàn)過程中指出一些輕易為人忽視的C++知識。
  要實現(xiàn)一個類的對象(實例)計數(shù),即程序運行中此類有多少個對象存在,最輕易的實現(xiàn)方法是使用靜態(tài)數(shù)據(jù)成員。如下: class Widget {public: Widget() { ++count; } Widget(const Widget&) { ++count; } ~Widget() { --count; } static size_t howMany() { return count; }PRivate: static size_t count;}; //cpp文件中size_t Widget::count = 0; 注重構(gòu)造函數(shù)也要增加計數(shù),這一點很多人輕易忘記。
  但是假如程序中有多個需要實例計數(shù)的類,則在每個類中加入上面代碼未免繁瑣、易錯。這種情況下,最好是實現(xiàn)一個通用計數(shù)類。它應(yīng)該具備一下特點:
  • 易于使用:任何需要計數(shù)的類(以下簡稱客戶類)只要添加少數(shù)代碼即可使用;
  • 有效率:不增加客戶類大小,對客戶類性能沒有影響;
  • 健壯:客戶類使用時,不輕易誤用。
  • 下面我們將逐步實現(xiàn)并完善這個通用的計數(shù)類。 class Counter { public: Counter() { ++count; } Counter(const Counter&) { ++count; } ~Counter() { --count; } static size_t howMany() { return count; }private: static size_t count;};// This still goes in an implementation filesize_t Counter::count = 0; 上面這個Counter類能否正確完成計數(shù)呢?例如:Widget類利用它來進行實例計數(shù): // embed a Counter to count objectsclass Widget {public: ..... // all the usual public // Widget stuff static size_t howMany() { return Counter::howMany(); }private: ..... // all the usual private // Widget stuff Counter c;}; //or:// inherit from Counter to count objectsclass Widget: public Counter { ..... // all the usual public // Widget stuffprivate: ..... // all the usual private // Widget stuff};   對于Widget本身來說,Counter完成了任務(wù)。然而,假如我們在同一進程中還需要利用Counter來計數(shù)Fish類,顯然,Counter就不能勝任,因為它只有一個靜態(tài)成員變量,它會將Widget和Fish的個數(shù)一起統(tǒng)計。這個方案不行,怎么辦?用模板!如下:template<typename T>class Counter {public: Counter() { ++count; } Counter(const Counter&) { ++count; } ~Counter() { --count; } static size_t howMany() { return count; }private: static size_t count;};// this now can go in headertemplate<typename T> size_t Counter<T>::count = 0; 則上面的實現(xiàn)變成: // embed a Counter to count objectsclass Widget {public: ..... static size_t howMany() {return Counter<Widget>::howMany();}private: ..... Counter<Widget> c;};//or:// inherit from Counter to count objectsclass Widget: public Counter<Widget> { .....};   這樣,其他類就可以使用Counter計數(shù)自己的實例了,它們將互不影響。
      上面兩種方案都可正確實現(xiàn)計數(shù),我們繼續(xù)探討這兩種方案的優(yōu)缺點。
      首先講public繼續(xù),即class Widget: public Counter<Widget>這種方案:有經(jīng)驗的讀者肯定會想到基類Counter的析構(gòu)函數(shù)要變?yōu)樘摵瘮?shù)。否則通過基類指針delete派生類時,結(jié)果未定義(可能導(dǎo)致程序crash或其他) Counter<Widget> *pw = new Widget; // get base class ptr to derived class object ......delete pw; // yields undefined results if the base class lacks a virtual destrUCtor   但一旦Counter有虛析構(gòu)函數(shù),就會給類帶入vTable,多占用了空間并影響客戶類的效率。解決方法可以是將析構(gòu)函數(shù)作為protected成員。這樣就不能delete pw,因為它會導(dǎo)致編譯錯誤。 template<typename T>
    class Counter {public: .....protected: ~Counter() { --count; } .....};   其次,Counter作為客戶類的成員變量這種方案(這時Counter的析構(gòu)函數(shù)必須public)。一個明顯的缺點是客戶類必須定義Counter為其成員變量同時還得定義一個inline函數(shù)以調(diào)用Counter類得HowMany函數(shù)。另一個較隱蔽的缺點:它增大了客戶類所占用的內(nèi)存。Counter類沒有非靜態(tài)成員變量,有人就可能會認為Counter對象的大小為0,其實不然,C++規(guī)定所有對象的大小最小必須為1字節(jié)。所以這用方案增加了客戶類的大小。使用派生則不一樣,基類size可以0,所以public繼續(xù)方案不會增加客戶類的大小。
      除了上面兩種方案,還可以使用private繼續(xù),即class Widget: private Counter<Widget>。類似于第一種方案: class Widget: private Counter<Widget> {public: // make howMany public using Counter<Widget>::howMany; ..... // rest of Widget is unchanged}; 它直接防止下面的代碼: Counter<Widget> *pw = new Widget; //私有繼續(xù)不答應(yīng)這樣轉(zhuǎn)換   綜合看來,public繼續(xù)方案已經(jīng)比較完善了。然而,還是有些值得注重的地方。假如有另一個類SpecialWidget,其繼續(xù)于Widget,對類SpecialWidget的對象計數(shù)就只能如下: class SpecialWidget: public Widget, public Counter<SpecialWidget> {public: };   這樣,對SpecialWidget的對象計數(shù)是正確的,但對Widget對象的計數(shù)是錯誤的。這時Widget的計數(shù)是Widget類的所有對象SpecialWidget類的所有對象的總和。為什么?因為每創(chuàng)建一個SpecialWidget對象,Widget構(gòu)造函數(shù)就要調(diào)用一次,就增加一次計數(shù)。

    總結(jié)
      用模板實現(xiàn)的這個對象計數(shù)類可以滿足絕大多數(shù)需求,但不適用于計數(shù)有繼續(xù)關(guān)系的類。本文的核心思想來源于CUG上C++大師Scott Meyers的一篇文章并有所改動。   

    發(fā)表評論 共有條評論
    用戶名: 密碼:
    驗證碼: 匿名發(fā)表
    主站蜘蛛池模板: 合山市| 邛崃市| 东乡县| 宜城市| 甘南县| 长岛县| 文成县| 滕州市| 房产| 上饶县| 华池县| 莫力| 泸州市| 吉水县| 盖州市| 兴隆县| 房山区| 丰都县| 如东县| 通江县| 东港市| 施秉县| 青浦区| 荆门市| 鄢陵县| 盈江县| 宁强县| 满城县| 永寿县| 清原| 郓城县| 赤城县| 丁青县| 南雄市| 那曲县| 固原市| 大同市| 高雄市| 项城市| 那坡县| 九龙县|