C++中靜態(tài)成員函數(shù)與靜態(tài)成員變量(static )
C++中靜態(tài)成員函數(shù)與靜態(tài)成員變量(static )
這篇介紹了靜態(tài)成員函數(shù)與靜態(tài)成員變量,是我的讀書(shū)筆記,我希望它夠簡(jiǎn)短但又比較全面,起到復(fù)習(xí)的作用。如果有一些C++知識(shí)記不清楚了,它可以幫你很快回憶起來(lái)。
復(fù)習(xí)C語(yǔ)言的static關(guān)鍵字
(1)加在局部變量的前面使之成為靜態(tài)局部變量,作用域還是在函數(shù)內(nèi)部,可是生存周期延長(zhǎng)了。
(2)加在全局變量的前面限定該變量作用域?yàn)槲募饔糜?,就是說(shuō)即使其他文件使用了extern擴(kuò)展作用域也不行。這在C語(yǔ)言的多人項(xiàng)目中非常有用,避免了變量的重名。然而在C++中這一功能已經(jīng)被命名空間取代,但是為了保持和C語(yǔ)言的兼容,static還是有這樣的功能。
(3)加在函數(shù)定義或聲明的前面,限定函數(shù)作用域到文件作用域,也是為了避免多個(gè)文件中有重名函數(shù)。
當(dāng)static關(guān)鍵字出現(xiàn)在類(lèi)中
當(dāng)static出現(xiàn)在類(lèi)的定義中便出現(xiàn)了靜態(tài)成員變量和靜態(tài)成員函數(shù)。靜態(tài)成員是屬于類(lèi)的,而不是屬于某個(gè)對(duì)象的。即便沒(méi)有任何一個(gè)實(shí)例,類(lèi)的靜態(tài)成員變量也已經(jīng)存在了,而且還可能通過(guò)“類(lèi)名::成員名”進(jìn)行訪(fǎng)問(wèn)。類(lèi)的靜態(tài)成員函數(shù)也可以用相同的方式調(diào)用,在類(lèi)產(chǎn)生實(shí)例之前就調(diào)用成員方法,典型應(yīng)用是實(shí)現(xiàn)單例模式。
(1)靜態(tài)成員變量
靜態(tài)成員變量本質(zhì)上是全局變量,但是將和某些類(lèi)關(guān)系緊密的全局變量寫(xiě)到類(lèi)里面,形式上成為一個(gè)整體,更容易理解和維護(hù)。所以盡量使用靜態(tài)成員變量吧,減少全局變量的使用。普通成員變量每個(gè)對(duì)象都有各自的一份,但是靜態(tài)成員變量一共只有一份,被所有的本類(lèi)對(duì)象共享。如果使用sizeof運(yùn)算符計(jì)算對(duì)象的大小,得到的結(jié)果是不包含靜態(tài)成員變量在內(nèi)的。
靜態(tài)成員同樣受到private,public等的限制。
靜態(tài)成員變量的一個(gè)典型應(yīng)用就是用來(lái)計(jì)數(shù)生成的實(shí)例的個(gè)數(shù)。大體思路是設(shè)置一個(gè)名為num的靜態(tài)成員變量并初始化為0,在構(gòu)造函數(shù)中++num,析構(gòu)函數(shù)中--num。這樣num的值就是當(dāng)前實(shí)例的個(gè)數(shù)。實(shí)際上這也帶來(lái)了一個(gè)隱蔽的bug??聪旅娴拇a:
class CNum {
   public:
       static int num;
       ~CNum() { --num; }
       CNum() { ++num; }
};
int CNum::num = 0;
void fun(CNum n){ }
 int main() {
   CNum n;
   fun(n);
   fun(n);
   cout << CNum::num << endl;
  return 0;
}
結(jié)果:-1
num盡然成了一個(gè)負(fù)數(shù),難道析構(gòu)函數(shù)比構(gòu)造函數(shù)多調(diào)用了一次?實(shí)際上不是的。當(dāng)執(zhí)行 fun(n); 語(yǔ)句時(shí)調(diào)用了復(fù)制構(gòu)造函數(shù),這個(gè)函數(shù)因?yàn)槲覀儧](méi)有給出實(shí)現(xiàn),所以是用的編譯器默認(rèn)提供的版本,在這個(gè)構(gòu)造函數(shù)中并沒(méi)有++num這條語(yǔ)句,因此少計(jì)數(shù)了兩次(兩次調(diào)用fun(n))。
解決的方法就是一定要提供自己寫(xiě)的復(fù)制構(gòu)造函數(shù)并在函數(shù)體中加入 ++num;
(2)靜態(tài)成員函數(shù)
靜態(tài)成員函數(shù)內(nèi)部不能調(diào)用非靜態(tài)成員函數(shù),原因是,非靜態(tài)成員函數(shù)需要傳入一個(gè)this指針,這讓靜態(tài)成員函數(shù)很為難,它并不知道與之相關(guān)的信息,也就無(wú)法提供this指針。
靜態(tài)成員變量的初始化
上面代碼中的第8行 int CNum::num = 0; 是靜態(tài)成員變量的初始化。這可以視為是靜態(tài)變量的定義(定義的同時(shí)初始化,即便不初始化也需要這個(gè)定義),而把類(lèi)內(nèi)的 static int num; 視為一個(gè)聲明,這樣的理解可以突出這樣一個(gè)事實(shí):靜態(tài)成員變量本質(zhì)上是全局變量。注意在類(lèi)外定義時(shí)加上“類(lèi)名::”。
對(duì)于常量成員變量,我們知道初始化時(shí)一定要使用初始化列表,那么當(dāng)一個(gè)變量既是常量又是靜態(tài)成員時(shí)(同時(shí)被const和static修飾)要怎么樣初始化呢?是像一般的靜態(tài)成員變量一樣在類(lèi)外定義并初始化,還是像一般的常量成員變量一樣使用初始化列表呢?答案時(shí)前者,即在類(lèi)外定義并初始化,在類(lèi)內(nèi)聲明,就像下面那樣:
class CNum {
   public:
      const static int num;
};
const int CNum::num = 0;
 int main() {
   CNum n;
  return 0;
}
實(shí)際上,完全可以把const int 視為一種數(shù)據(jù)類(lèi)型,它的地位和int一樣。這樣理解是有好處的,比如從const int到int需要強(qiáng)制類(lèi)型轉(zhuǎn)換,把他們看成兩種類(lèi)型,這就自然而然。相應(yīng)的const char 和char 也應(yīng)該看成兩種類(lèi)型,就好像它們完全沒(méi)有什么特殊的關(guān)系一樣。
另外static const int類(lèi)型和static const char 類(lèi)型可以在類(lèi)內(nèi)直接初始化,就是說(shuō)都不需要在類(lèi)外再次定義,像下面這樣:
class CNum {
   public:
     const static int a = 19;
};
 int main() { 8   cout << CNum::a << endl;    //輸出19
  return 0;
}
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
欄 目:C語(yǔ)言
下一篇:OPENCV批量讀取圖片實(shí)現(xiàn)方法
本文標(biāo)題:C++中靜態(tài)成員函數(shù)與靜態(tài)成員變量(static )
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/1450.html
您可能感興趣的文章
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
 - 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)數(shù)怎么表達(dá)
 - 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
 - 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎么打出三角函數(shù)的值
 - 01-10深入理解C++中常見(jiàn)的關(guān)鍵字含義
 - 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
 - 01-10深入Main函數(shù)中的參數(shù)argc,argv的使用詳解
 - 01-10APUE筆記之:進(jìn)程環(huán)境詳解
 - 01-10c++中inline的用法分析
 - 01-10如何尋找數(shù)組中的第二大數(shù)
 


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
 - 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
 - 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
 - 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
 - 5c語(yǔ)言計(jì)算三角形面積代碼
 - 6什么是 WSH(腳本宿主)的詳細(xì)解釋
 - 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
 - 8正則表達(dá)式匹配各種特殊字符
 - 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
 - 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
 
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
 - 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
 - 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
 - 04-02c語(yǔ)言用函數(shù)寫(xiě)分段 用c語(yǔ)言表示分段
 - 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
 - 04-02c語(yǔ)言編寫(xiě)函數(shù)冒泡排序 c語(yǔ)言冒泡排
 - 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
 - 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
 - 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
 - 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
 
隨機(jī)閱讀
- 01-10C#中split用法實(shí)例總結(jié)
 - 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
 - 04-02jquery與jsp,用jquery
 - 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
 - 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
 - 01-10delphi制作wav文件的方法
 - 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
 - 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
 - 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
 - 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
 


