程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++中靜態成員函數與靜態成員變量(static )

C++中靜態成員函數與靜態成員變量(static )

編輯:關於C++

C++中靜態成員函數與靜態成員變量(static )。本站提示廣大學習愛好者:(C++中靜態成員函數與靜態成員變量(static ))文章只能為提供參考,不一定能成為您想要的結果。以下是C++中靜態成員函數與靜態成員變量(static )正文


C++中靜態成員函數與靜態成員變量(static )

投稿:lqh

這篇文章主要介紹了C++中靜態成員函數與靜態成員變量(static )的相關資料,需要的朋友可以參考下

C++中靜態成員函數與靜態成員變量(static )

這篇介紹了靜態成員函數與靜態成員變量,是我的讀書筆記,我希望它夠簡短但又比較全面,起到復習的作用。如果有一些C++知識記不清楚了,它可以幫你很快回憶起來。

復習C語言的static關鍵字

(1)加在局部變量的前面使之成為靜態局部變量,作用域還是在函數內部,可是生存周期延長了。

(2)加在全局變量的前面限定該變量作用域為文件作用域,就是說即使其他文件使用了extern擴展作用域也不行。這在C語言的多人項目中非常有用,避免了變量的重名。然而在C++中這一功能已經被命名空間取代,但是為了保持和C語言的兼容,static還是有這樣的功能。

(3)加在函數定義或聲明的前面,限定函數作用域到文件作用域,也是為了避免多個文件中有重名函數。

當static關鍵字出現在類中

當static出現在類的定義中便出現了靜態成員變量和靜態成員函數。靜態成員是屬於類的,而不是屬於某個對象的。即便沒有任何一個實例,類的靜態成員變量也已經存在了,而且還可能通過“類名::成員名”進行訪問。類的靜態成員函數也可以用相同的方式調用,在類產生實例之前就調用成員方法,典型應用是實現單例模式。

(1)靜態成員變量

靜態成員變量本質上是全局變量,但是將和某些類關系緊密的全局變量寫到類裡面,形式上成為一個整體,更容易理解和維護。所以盡量使用靜態成員變量吧,減少全局變量的使用。普通成員變量每個對象都有各自的一份,但是靜態成員變量一共只有一份,被所有的本類對象共享。如果使用sizeof運算符計算對象的大小,得到的結果是不包含靜態成員變量在內的。

靜態成員同樣受到private,public等的限制。

靜態成員變量的一個典型應用就是用來計數生成的實例的個數。大體思路是設置一個名為num的靜態成員變量並初始化為0,在構造函數中++num,析構函數中--num。這樣num的值就是當前實例的個數。實際上這也帶來了一個隱蔽的bug。看下面的代碼:

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;
}

結果:-1

num盡然成了一個負數,難道析構函數比構造函數多調用了一次?實際上不是的。當執行 fun(n); 語句時調用了復制構造函數,這個函數因為我們沒有給出實現,所以是用的編譯器默認提供的版本,在這個構造函數中並沒有++num這條語句,因此少計數了兩次(兩次調用fun(n))。

解決的方法就是一定要提供自己寫的復制構造函數並在函數體中加入 ++num;

(2)靜態成員函數

靜態成員函數內部不能調用非靜態成員函數,原因是,非靜態成員函數需要傳入一個this指針,這讓靜態成員函數很為難,它並不知道與之相關的信息,也就無法提供this指針。

靜態成員變量的初始化

上面代碼中的第8行  int CNum::num = 0; 是靜態成員變量的初始化。這可以視為是靜態變量的定義(定義的同時初始化,即便不初始化也需要這個定義),而把類內的 static int num; 視為一個聲明,這樣的理解可以突出這樣一個事實:靜態成員變量本質上是全局變量。注意在類外定義時加上“類名::”。

對於常量成員變量,我們知道初始化時一定要使用初始化列表,那麼當一個變量既是常量又是靜態成員時(同時被const和static修飾)要怎麼樣初始化呢?是像一般的靜態成員變量一樣在類外定義並初始化,還是像一般的常量成員變量一樣使用初始化列表呢?答案時前者,即在類外定義並初始化,在類內聲明,就像下面那樣:

class CNum {
   public:
      const static int num;
};

const int CNum::num = 0;

 int main() {
   CNum n;
  return 0;
}

實際上,完全可以把const int 視為一種數據類型,它的地位和int一樣。這樣理解是有好處的,比如從const int到int需要強制類型轉換,把他們看成兩種類型,這就自然而然。相應的const char 和char 也應該看成兩種類型,就好像它們完全沒有什麼特殊的關系一樣。

另外static const int類型和static const char 類型可以在類內直接初始化,就是說都不需要在類外再次定義,像下面這樣:

class CNum {
   public:
     const static int a = 19;
};


 int main() { 8   cout << CNum::a << endl;    //輸出19
  return 0;
}

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved