詳解c++ 靜態(tài)成員變量
類定義時(shí)的靜態(tài)成員只是聲明,靜態(tài)成員的定義和初始化要在類之外完成
C++的static
關(guān)鍵字可修飾類成員變量/方法,表示變量/方法不從屬于特定對象,而是屬于類的。仔細(xì)琢磨靜態(tài)成員變量,會發(fā)現(xiàn)其與C++的方式既相容也矛盾,具有特殊性。
先說相容的一面?!/C++·有聲明和定義的說法:聲明給出簽名,定義給出具體實(shí)現(xiàn)。對類型而言,聲明不一定能知道其對象占用空間大小,但根據(jù)定義肯定能確定內(nèi)存占用。說靜態(tài)成員與C++方式是相容的,因?yàn)槠涑跏蓟绞脚c方法的定義一致。下面是一個(gè)例子:
// Foo.hpp namespace tlanyan { // 類聲明和定義 class Foo { private: // 聲明靜態(tài)成員 static int value; public: // 方法聲明 void increaseValue(); int getValue() const; }; } // Foo.cpp namespace tlanyan { // 定義靜態(tài)成員變量并初始化 int Foo::value = 0; // 類方法定義 void Foo::increaseValue() { ++ value; } int Foo::getValue() { return value; } }
相對于相容點(diǎn),靜態(tài)成員變量更多展現(xiàn)出怪異的一面,以下是個(gè)人總結(jié):
- 靜態(tài)成員不能在類中初始化;非靜態(tài)成員可直接初始化,靜態(tài)成員在類中只是聲明,所以不能直接初始化。輔以
const
的靜態(tài)成員可以直接初始化,但那是const
的能力而非static
所有; - 對靜態(tài)成員初始化,需要在類之外定義時(shí)再完成;
- 初始化時(shí)不受訪問修飾符限制;
private
類型的靜態(tài)成員可直接訪問并賦值; - 靜態(tài)成員初始化時(shí)可調(diào)用函數(shù),并且可以直接調(diào)用所屬類的私有函數(shù);
其中第4點(diǎn)比較重要。在不支持C++11的編譯器上,要完成靜態(tài)map成員,就不得不借助函數(shù)返回:
#include <map> // 類定義 class Foo { private: std::map<const char*, int> maps; ... } // 靜態(tài)成員初始化 std::map<const char*, int> Foo::maps = Foo::initMap(); // 或者使用全局函數(shù) std::map<const char*, int> Foo::maps = initMap();
C++11引入了統(tǒng)一初始化和lambda
表達(dá)式,初始化的寫法更為簡單:
// 統(tǒng)一初始化 std::map<const char*, int> Foo::maps { {"a", 31}, {"b", 32} }; // lambda表達(dá)式方式 std::map<const char*, int> Foo::maps = [] { map<const char*, int> _map; _map.insert(map<const char*, int>::value_type("a", 31)); _map.insert(map<const char*, int>::value_type("a", 32)); return _map; }();
靜態(tài)成員的這些異常行為很容易聯(lián)想到全局變量,兩者有許多相通的地方:在程序啟動前完成初始化,在程序終止后銷毀;存放的地方都是靜態(tài)存儲區(qū)而非堆棧;通過名字空間操作符獲取值;在非函數(shù)塊內(nèi)通過函數(shù)調(diào)用或者lambda表達(dá)式完成初始化…
雖然各種面向?qū)ο缶幊陶Z言都有靜態(tài)變量,并且使用比例不低。但從面向?qū)ο蟮慕嵌?,靜態(tài)成員是另一種形式的全局變量,其破壞了隔離和封裝,增加了類之間的耦合,讓測試變得更困難。實(shí)際編程中,應(yīng)當(dāng)慎用全局變量,并收緊其訪問權(quán)限。
所以本質(zhì)上靜態(tài)成員也是全局變量,只是歸屬到特定類的名下。
以上就是詳解c++ 靜態(tài)成員變量的詳細(xì)內(nèi)容,更多關(guān)于c++ 靜態(tài)成員變量的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C++中const、volatile、mutable使用方法小結(jié)
這篇文章主要介紹了C++中const、volatile、mutable使用方法小結(jié),需要的朋友可以參考下2020-01-01C++實(shí)現(xiàn)LeetCode(64.最小路徑和)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(64.最小路徑和),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C++深入探索內(nèi)聯(lián)函數(shù)inline與auto關(guān)鍵字的使用
本篇文章主要包括內(nèi)聯(lián)函數(shù)和auto關(guān)鍵字。其中,內(nèi)斂函數(shù)包括概念,特性等;auto關(guān)鍵字的使用規(guī)則,使用場景等,接下來讓我們深入了解2022-05-05C++非遞歸隊(duì)列實(shí)現(xiàn)二叉樹的廣度優(yōu)先遍歷
這篇文章主要介紹了C++非遞歸隊(duì)列實(shí)現(xiàn)二叉樹的廣度優(yōu)先遍歷,實(shí)例分析了遍歷二叉樹相關(guān)算法技巧,并附帶了兩個(gè)相關(guān)算法實(shí)例,需要的朋友可以參考下2015-07-07使用C語言打造通訊錄管理系統(tǒng)和教學(xué)安排系統(tǒng)的代碼示例
這篇文章主要介紹了使用C語言打造通訊錄管理系統(tǒng)和教學(xué)安排系統(tǒng)的代碼示例,利用C語言強(qiáng)大的數(shù)組和指針能夠更加清晰地體現(xiàn)設(shè)計(jì)思路:D 需要的朋友可以參考下2016-06-06