您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關c++ 靜態成員變量的深入淺析,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
類定義時的靜態成員只是聲明,靜態成員的定義和初始化要在類之外完成
C++的static
關鍵字可修飾類成員變量/方法,表示變量/方法不從屬于特定對象,而是屬于類的。仔細琢磨靜態成員變量,會發現其與C++的方式既相容也矛盾,具有特殊性。
先說相容的一面。·C/C++·有聲明和定義的說法:聲明給出簽名,定義給出具體實現。對類型而言,聲明不一定能知道其對象占用空間大小,但根據定義肯定能確定內存占用。說靜態成員與C++方式是相容的,因為其初始化方式與方法的定義一致。下面是一個例子:
// Foo.hpp namespace tlanyan { // 類聲明和定義 class Foo { private: // 聲明靜態成員 static int value; public: // 方法聲明 void increaseValue(); int getValue() const; }; } // Foo.cpp namespace tlanyan { // 定義靜態成員變量并初始化 int Foo::value = 0; // 類方法定義 void Foo::increaseValue() { ++ value; } int Foo::getValue() { return value; } }
相對于相容點,靜態成員變量更多展現出怪異的一面,以下是個人總結:
const
的靜態成員可以直接初始化,但那是const
的能力而非static
所有;private
類型的靜態成員可直接訪問并賦值;其中第4點比較重要。在不支持C++11的編譯器上,要完成靜態map成員,就不得不借助函數返回:
#include <map> // 類定義 class Foo { private: std::map<const char*, int> maps; ... } // 靜態成員初始化 std::map<const char*, int> Foo::maps = Foo::initMap(); // 或者使用全局函數 std::map<const char*, int> Foo::maps = initMap();
C++11引入了統一初始化和lambda
表達式,初始化的寫法更為簡單:
// 統一初始化 std::map<const char*, int> Foo::maps { {"a", 31}, {"b", 32} }; // lambda表達式方式 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; }();
靜態成員的這些異常行為很容易聯想到全局變量,兩者有許多相通的地方:在程序啟動前完成初始化,在程序終止后銷毀;存放的地方都是靜態存儲區而非堆棧;通過名字空間操作符獲取值;在非函數塊內通過函數調用或者lambda表達式完成初始化…
雖然各種面向對象編程語言都有靜態變量,并且使用比例不低。但從面向對象的角度,靜態成員是另一種形式的全局變量,其破壞了隔離和封裝,增加了類之間的耦合,讓測試變得更困難。實際編程中,應當慎用全局變量,并收緊其訪問權限。
所以本質上靜態成員也是全局變量,只是歸屬到特定類的名下。
關于c++ 靜態成員變量的深入淺析就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。