這篇來學習在一個類中,用關鍵字static修飾成員變量和成員函數。前面我們知道,一個類主要有兩類,一個是屬性,也叫類成員變量,還有一個是類的行為,或者叫成員方法。如果在類的成員變量和類的成員方法前面加上關鍵字static修飾,就變成了靜态成員變量和靜态成員方法。
1.定義
靜态成員就是在成員變量和成員函數加上關鍵字static,稱為靜态成員。
2.分類
靜态成員分為:靜态成員變量和靜态成員函數,本篇先學習靜态成員變量。
靜态成員變量:
- 所有對象共享同一份資料
- 在編譯階段配置設定記憶體
- 類内聲明,類外初始化
看看這幾個特點,第一個所有對象共享同一份資料,就是這個static修飾的變量,不管這個類執行個體化多少個對象,隻要有一個對象修改了這個變量,其他對象通路這個static變量,值都會修改,實際上在記憶體中,執行個體化出來多個對象,都共享一個記憶體空間用來存儲static修飾的變量。
在編譯階段配置設定記憶體,這個就是在生成可執行檔案exe之前,static修飾的變量就配置設定了記憶體。第三點,類内聲明,類外初始化,怎麼做呢,下面代碼來解釋這句話。
#include<iostream>
using namespace std;
class Person
{
public:
//類内定義靜态成員變量
static int m_A;
};
//類外進行初始化
int Person::m_A = 100;
void test01()
{
Person p;
cout << "靜态成員變量A的值為:" << p.m_A << endl;
p.m_A = 200;
cout << "靜态成員變量A的值為:" << p.m_A << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
上面在類内隻是定義了一個靜态成員 m_A, 而初始化是在類的外面進行,也就是指派100這行代碼。上面代碼運作之後結果
這裡我們執行個體化兩個Person對象,p和p1,分别修改靜态變量m_A的值,看看是不是共享一份資料的特點。(隻修改test01()的代碼)
void test01()
{
Person p;
cout << "靜态成員變量A的值為:" << p.m_A << endl;
p.m_A = 200;
cout << "靜态成員變量A的值為:" << p.m_A << endl;
Person p1;
p1.m_A = 300;
cout << "靜态成員變量A的值為:" << p.m_A << endl;
}
運作效果
這個結果,說明p和p1共享一份m_A這個資料,p1進行了修改成了300,p去通路也就值列印為300
靜态成員變量的兩種通路方式
方式一:執行個體化對象調用(p.m_A)
方式二:直接通過類名通路
以上兩種方式都可以。
私有靜态成員變量,類外不可以通路
關于這個,我們來看看例子
在類外test01()中不能通路私有靜态成員變量m_B;
3.靜态成員函數
靜态成員函數特點
- 所有對象共享一個函數
- 靜态成員函數隻能通路靜态成員變量
靜态成員函數通路也是兩種和靜态成員變量一樣,下面來看看,同時說明以上第一個特點,共享一個函數。
#include<iostream>
using namespace std;
class Person
{
public:
//類内定義靜态成員變量
static int m_A;
static void func()
{
cout << "static void func()進行了調用" << endl;
}
};
//類外進行初始化
int Person::m_A = 100;
void test01()
{
//方式一:執行個體化對象通過點(.)調用通路
Person p;
p.func();
//方式二:直接通過類名(作用範圍格式)通路
Person::func();
}
int main()
{
test01();
system("pause");
return 0;
}
運作結果
靜态成員函數隻能通路靜态成員變量,非靜态成員變量不可以通路
下面用代碼來證明這個特點,在以上代碼基礎,新增一個非靜态成員變量
是以,在靜态成員函數中,隻能通路靜态成員的變量,非靜态的變量不能通路。