<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
這裡先參照GeeksforGeeks的一段內容:
Static data members are class members that are declared using static keywords. A static member has certain special characteristics. These are:
語法: static data_type data_member_name;
我們看程式碼範例,一碼勝千言
#include <iostream> using namespace std; class A { public: A() { cout << "A constructed" << endl; } }; class B { static A a; public: B() { cout << "B constructed" << endl; } }; int main() { B b; return 0; } // output B constructed
我們看到B類有一個靜態成員A類,但是在建立B的物件時並沒有呼叫A的建構函式,原因很簡單,即在類B中僅僅宣告(declare)了靜態類A,但沒有在類外定義(define)它。 如果我們在靜態成員變數定義前使用它,那麼會編譯報錯,這和程式碼塊中的靜態變數不同,程式碼塊中的靜態變數會有常數初始化的過程,程式碼範例如下。
#include <iostream> using namespace std; class A { public: int x; A() { cout << "A constructed" << endl; } }; class B { static A a; public: B() { cout << "B constructed" << endl; } static A getA() {return a;} }; int main() { B b; // A a = b.getA(); // ERROR Compiler Error: undefined reference to `B::a' static int n; cout << n << endl; // ok 0 return 0; }
我們在類內定義靜態成員變數時需要 static,在類外定義鏡頭成員變數時不用 static,語法如下。
class X { static int n; }; // declaration (uses 'static') int X::n = 1; // definition (does not use 'static')
這裡需要注意幾點:
我們考慮下為什麼不能在宣告中初始化靜態變數,這是因為宣告描述來如何分配記憶體,但不分配記憶體。這裡我們還是使用上面程式碼的例子來說明。
using namespace std; class A { public: int x; A() { cout << "A's constructor called " << endl; } }; class B { static A a; public: B() { cout << "B's constructor called " << endl; } static A getA() { return a; } }; A B::a; // definition of a int main() { B b1, b2, b3; A a = b1.getA(); cout << a.x << endl; // 0 return 0; }
output
A's constructor called B's constructor called B's constructor called B's constructor called 0
從上述結果我們也可以看出來靜態成員變數確實在建立類物件之前初始化。
有兩種方法可以參照靜態成員變數,<類物件名>.<靜態資料成員名>
或 <類型別名>::<靜態資料成員名>
To refer to a static member m of class T, two forms may be used: qualified name T::m or member access expression E.m or E->m, where E is an expression that evaluates to T or T* respectively. When in the same class scope, the qualification is unnecessary:
struct X { static void f(); // declaration static int n; // declaration }; X g() { return X(); } // some function returning X void f() { X::f(); // X::f is a qualified name of static member function g().f(); // g().f is member access expression referring to a static member function } int X::n = 7; // definition void X::f() // definition { n = 1; // X::n is accessible as just n in this scope }
靜態類成員有一個特點:無論建立了多少個物件,程式都只建立一個靜態類變數副本。也就是說,類的所有物件共用同一個靜態成員。靜態資料成員和普通資料成員一樣遵從public,protected,private存取規則;
接下來看另一個程式碼範例
#include <iostream> using namespace std; class A { public: static int x; int y; static void f() { // y++; Error invalid use of member 'y' in static member function x++; cout << "A static function, x = " << x << endl; } }; int A::x; int main() { A a; cout << "x = " << A::x << endl; cout << "x = " << a.x << endl; A::f(); a.f(); return 0; }
output
x = 0 x = 0 A static function, x = 1 A static function, x = 2
C++提供了多種在類中定義常數的方式,其中比較常用的有 const
,constexpr
和enum
class X { // method1 const const static int n = 1; const static int m{2}; // since C++11 const static int k; // ok // method2 enum enum {Month=12}; // method3 constexpr constexpr static int arr[] = { 1, 2, 3 }; // OK constexpr static std::complex<double> n = {1,2}; // OK constexpr static int k; // Error: constexpr static requires an initializer }; const int X::k = 3;
其中注意:
1.使用 enum 時並不會建立資料成員,即所有的物件中都不包括列舉,另外Month知識一個符號名稱,在作用於為整個類的程式碼中遇到它是,編譯器將用12來替代它。而且只能是整數。
2.使用 constexpr 來建立類常數時,一定要給其定義,不能只是宣告,而const可以只是宣告,不用給出定義。
#include <iostream> using namespace std; class Person { public: Person() {}; Person(char *name, int age); void show(); static int getTotal(); private: static int m_total; char *m_name; int m_age; }; Person::Person(char *name, int age) : m_name(name), m_age(age) { m_total++; } void Person::show() { cout << m_name << "的年齡是" << m_age << ", 總人數是" << m_total << endl; } int Person::getTotal() { return m_total; } // 一定要先初始化 int Person::m_total = 0; int main() { Person *p1 = new Person("Alice", 18); Person *p2 = new Person("Bob", 18); p1->show(); p2->show(); int total1 = Person::getTotal(); int total2 = p1->getTotal(); cout << "total1 = " << total1 << ", total2 = " << total2 << endl; return 0; }
靜態成員函數與普通成員函數的根本區別在於:普通成員函數有 this 指標,可以存取類中的任意成員;而靜態成員函數沒有 this 指標,只能存取靜態成員(包括靜態成員變數和靜態成員函數)。這裡要注意的是普通的成員函數也能存取靜態成員變數。這一點上和Java中的static用法很像。
本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注it145.com的更多內容!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45