溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

c++ 靜態(tài)成員變量的深入淺析

發(fā)布時(shí)間:2020-11-04 15:48:39 來源:億速云 閱讀:183 作者:Leah 欄目:開發(fā)技術(shù)

這篇文章將為大家詳細(xì)講解有關(guān)c++ 靜態(tài)成員變量的深入淺析,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

類定義時(shí)的靜態(tài)成員只是聲明,靜態(tài)成員的定義和初始化要在類之外完成

C++的static關(guān)鍵字可修飾類成員變量/方法,表示變量/方法不從屬于特定對(duì)象,而是屬于類的。仔細(xì)琢磨靜態(tài)成員變量,會(huì)發(fā)現(xiàn)其與C++的方式既相容也矛盾,具有特殊性。

先說相容的一面?!/C++·有聲明和定義的說法:聲明給出簽名,定義給出具體實(shí)現(xiàn)。對(duì)類型而言,聲明不一定能知道其對(duì)象占用空間大小,但根據(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;
 }
}

相對(duì)于相容點(diǎn),靜態(tài)成員變量更多展現(xiàn)出怪異的一面,以下是個(gè)人總結(jié):

  1. 靜態(tài)成員不能在類中初始化;非靜態(tài)成員可直接初始化,靜態(tài)成員在類中只是聲明,所以不能直接初始化。輔以const的靜態(tài)成員可以直接初始化,但那是const的能力而非static所有;
  2. 對(duì)靜態(tài)成員初始化,需要在類之外定義時(shí)再完成;
  3. 初始化時(shí)不受訪問修飾符限制;private類型的靜態(tài)成員可直接訪問并賦值;
  4. 靜態(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á)式,初始化的寫法更為簡(jiǎn)單:

// 統(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)存儲(chǔ)區(qū)而非堆棧;通過名字空間操作符獲取值;在非函數(shù)塊內(nèi)通過函數(shù)調(diào)用或者lambda表達(dá)式完成初始化…

雖然各種面向?qū)ο缶幊陶Z言都有靜態(tài)變量,并且使用比例不低。但從面向?qū)ο蟮慕嵌?,靜態(tài)成員是另一種形式的全局變量,其破壞了隔離和封裝,增加了類之間的耦合,讓測(cè)試變得更困難。實(shí)際編程中,應(yīng)當(dāng)慎用全局變量,并收緊其訪問權(quán)限。

所以本質(zhì)上靜態(tài)成員也是全局變量,只是歸屬到特定類的名下。

關(guān)于c++ 靜態(tài)成員變量的深入淺析就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI