詳解c++ 靜態(tài)成員變量
類定義時(shí)的靜態(tài)成員只是聲明,靜態(tài)成員的定義和初始化要在類之外完成
C++的static關(guān)鍵字可修飾類成員變量/方法,表示變量/方法不從屬于特定對象,而是屬于類的。仔細(xì)琢磨靜態(tài)成員變量,會發(fā)現(xiàn)其與C++的方式既相容也矛盾,具有特殊性。
先說相容的一面。·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)想到全局變量,兩者有許多相通的地方:在程序啟動(dòng)前完成初始化,在程序終止后銷毀;存放的地方都是靜態(tài)存儲區(qū)而非堆棧;通過名字空間操作符獲取值;在非函數(shù)塊內(nèi)通過函數(shù)調(diào)用或者lambda表達(dá)式完成初始化…
雖然各種面向?qū)ο缶幊陶Z言都有靜態(tài)變量,并且使用比例不低。但從面向?qū)ο蟮慕嵌龋o態(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)文章
Qt+QWidget實(shí)現(xiàn)簡約美觀的加載動(dòng)畫
這篇文章主要為大家詳細(xì)介紹了Qt如何結(jié)合QWidget實(shí)現(xiàn)簡約美觀的加載動(dòng)畫,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-02-02
JS調(diào)用C++函數(shù)拋出異常及捕捉異常詳解
這篇文章主要介紹了js調(diào)用C++函數(shù)的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2021-08-08
C++編譯錯(cuò)誤variable-sized?object?may?not?be?initiali問題
這篇文章主要介紹了C++編譯錯(cuò)誤variable-sized?object?may?not?be?initiali問題及解決,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05
一文帶你搞懂C語言動(dòng)態(tài)內(nèi)存管理
動(dòng)態(tài)內(nèi)存是指在堆上分配的內(nèi)存,而靜態(tài)內(nèi)存是指在棧上分配的內(nèi)存。本文將通過幾個(gè)示例帶大家深入了解一下C語言的動(dòng)態(tài)內(nèi)存管理,需要的可以參考一下2022-11-11
數(shù)據(jù)結(jié)構(gòu)串的操作實(shí)例詳解
這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)串的操作實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-07-07

