C++ 類的靜態(tài)成員深入解析
在C++中,靜態(tài)成員是屬于整個類的而不是某個對象,靜態(tài)成員變量只存儲一份供所有對象共用。所以在所有對象中都可以共享它。使用靜態(tài)成員變量實現(xiàn)多個對象之間的數(shù)據(jù)共享不會破壞隱藏的原則,保證了安全性還可以節(jié)省內(nèi)存。
靜態(tài)成員的定義或聲明要加個關(guān)鍵static。靜態(tài)成員可以通過雙冒號來使用即<類名>::<靜態(tài)成員名>。
在C++中類的靜態(tài)成員變量和靜態(tài)成員函數(shù)是個容易出錯的地方,本文先通過幾個例子來總結(jié)靜態(tài)成員變量和成員函數(shù)使用規(guī)則,再給出一個實例來加深印象。希望閱讀本文可以使讀者對類的靜態(tài)成員變量和成員函數(shù)有更為深刻的認(rèn)識。
第一個例子,通過類名調(diào)用靜態(tài)成員函數(shù)和非靜態(tài)成員函數(shù)
class Point
{
public:
void init()
{
}
static void output()
{
}
};
void main()
{
Point::init();
Point::output();
}
編譯出錯:error C2352: 'Point::init' : illegal call of non-static member function
結(jié)論1:不能通過類名來調(diào)用類的非靜態(tài)成員函數(shù)。
第二個例子,通過類的對象調(diào)用靜態(tài)成員函數(shù)和非靜態(tài)成員函數(shù)
將上例的main()改為:
void main()
{
Point pt;
pt.init();
pt.output();
}
編譯通過。
結(jié)論2:類的對象可以使用靜態(tài)成員函數(shù)和非靜態(tài)成員函數(shù)。
第三個例子,在類的靜態(tài)成員函數(shù)中使用類的非靜態(tài)成員
#include <stdio.h>
class Point
{
public:
void init()
{
}
static void output()
{
printf("%d\n", m_x);
}
private:
int m_x;
};
void main()
{
Point pt;
pt.output();
}
編譯出錯:error C2597: illegal reference to data member 'Point::m_x' in a static member function
因為靜態(tài)成員函數(shù)屬于整個類,在類實例化對象之前就已經(jīng)分配空間了,而類的非靜態(tài)成員必須在類實例化對象后才有內(nèi)存空間,所以這個調(diào)用就出錯了,就好比沒有聲明一個變量卻提前使用它一樣。
結(jié)論3:靜態(tài)成員函數(shù)中不能引用非靜態(tài)成員。
第四個例子,在類的非靜態(tài)成員函數(shù)中使用類的靜態(tài)成員
class Point
{
public:
void init()
{
output();
}
static void output()
{
}
};
void main()
{
Point pt;
pt.output();
}
編譯通過。
結(jié)論4:類的非靜態(tài)成員函數(shù)可以調(diào)用用靜態(tài)成員函數(shù),但反之不能。
第五個例子,使用類的靜態(tài)成員變量
#include <stdio.h>
class Point
{
public:
Point()
{
m_nPointCount++;
}
~Point()
{
m_nPointCount--;
}
static void output()
{
printf("%d\n", m_nPointCount);
}
private:
static int m_nPointCount;
};
void main()
{
Point pt;
pt.output();
}
按Ctrl+F7編譯無錯誤,按F7生成EXE程序時報鏈接錯誤
error LNK2001: unresolved external symbol "private: static int Point::m_nPointCount" (?m_nPointCount@Point@@0HA)
這是因為類的靜態(tài)成員變量在使用前必須先初始化。
在main()函數(shù)前加上int Point::m_nPointCount = 0;
再編譯鏈接無錯誤,運行程序?qū)⑤敵?。
結(jié)論5:類的靜態(tài)成員變量必須先初始化再使用。
結(jié)合上面的五個例子,對類的靜態(tài)成員變量和成員函數(shù)作個總結(jié):
一。靜態(tài)成員函數(shù)中不能調(diào)用非靜態(tài)成員。
二。非靜態(tài)成員函數(shù)中可以調(diào)用靜態(tài)成員。因為靜態(tài)成員屬于類本身,在類的對象產(chǎn)生之前就已經(jīng)存在了,所以在非靜態(tài)成員函數(shù)中是可以調(diào)用靜態(tài)成員的。
三。靜態(tài)成員變量使用前必須先初始化(如int MyClass::m_nNumber = 0;),否則會在linker時出錯。
再給一個利用類的靜態(tài)成員變量和函數(shù)的例子以加深理解,這個例子建立一個學(xué)生類,每個學(xué)生類的對象將組成一個雙向鏈表,用一個靜態(tài)成員變量記錄這個雙向鏈表的表頭,一個靜態(tài)成員函數(shù)輸出這個雙向鏈表。
#include <stdio.h>
#include <string.h>
const int MAX_NAME_SIZE = 30;
class Student
{
public:
Student(char *pszName);
~Student();
public:
static void PrintfAllStudents();
private:
char m_name[MAX_NAME_SIZE];
Student *next;
Student *prev;
static Student *m_head;
};
Student::Student(char *pszName)
{
strcpy(this->m_name, pszName);
//建立雙向鏈表,新數(shù)據(jù)從鏈表頭部插入。
this->next = m_head;
this->prev = NULL;
if (m_head != NULL)
m_head->prev = this;
m_head = this;
}
Student::~Student ()//析構(gòu)過程就是節(jié)點的脫離過程
{
if (this == m_head) //該節(jié)點就是頭節(jié)點。
{
m_head = this->next;
}
else
{
this->prev->next = this->next;
this->next->prev = this->prev;
}
}
void Student::PrintfAllStudents()
{
for (Student *p = m_head; p != NULL; p = p->next)
printf("%s\n", p->m_name);
}
Student* Student::m_head = NULL;
void main()
{
Student studentA("AAA");
Student studentB("BBB");
Student studentC("CCC");
Student studentD("DDD");
Student student("MoreWindows");
Student::PrintfAllStudents();
}
程序?qū)⑤敵觯?br>
當(dāng)然在本例還可以增加個靜態(tài)成員變量來表示鏈表中學(xué)生個數(shù),如果讀者有興趣,就將這個作為小練習(xí)吧。
上一篇:C++類靜態(tài)成員與類靜態(tài)成員函數(shù)詳解
欄 目:C語言
本文標(biāo)題:C++ 類的靜態(tài)成員深入解析
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/4047.html
您可能感興趣的文章
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)式函數(shù)庫
- 04-02c語言中對數(shù)函數(shù)的表達(dá)式 c語言中對數(shù)怎么表達(dá)
- 04-02c語言沒有round函數(shù) round c語言
- 04-02C語言中怎么打出三角函數(shù) c語言中怎么打出三角函數(shù)的值
- 01-10c語言求1+2+...+n的解決方法
- 01-10求子數(shù)組最大和的解決方法詳解
- 01-10深入理解約瑟夫環(huán)的數(shù)學(xué)優(yōu)化方法
- 01-10深入二叉樹兩個結(jié)點的最低共同父結(jié)點的詳解
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設(shè)計- 解析最少換車次數(shù)的問題詳解
- 01-10c語言 跳臺階問題的解決方法


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達(dá)式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機(jī)閱讀
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10delphi制作wav文件的方法
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10C#中split用法實例總結(jié)
- 04-02jquery與jsp,用jquery
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文