C++ 類的靜態成員深刻解析。本站提示廣大學習愛好者:(C++ 類的靜態成員深刻解析)文章只能為提供參考,不一定能成為您想要的結果。以下是C++ 類的靜態成員深刻解析正文
在C++中,靜態成員是屬於全部類的而不是某個對象,靜態成員變量只存儲一份供一切對象共用。所以在一切對象中都可以同享它。應用靜態成員變量完成多個對象之間的數據同享不會損壞隱蔽的准繩,包管了平安性還可以節儉內存。
靜態成員的界說或聲明要加個症結static。靜態成員可以經由過程雙冒號來應用即<類名>::<靜態成員名>。
在C++中類的靜態成員變量和靜態成員函數是個輕易失足的處所,本文先經由過程幾個例子來總結靜態成員變量和成員函數應用規矩,再給出一個實例來加深印象。願望浏覽本文可使讀者對類的靜態成員變量和成員函數有更加深入的熟悉。
第一個例子,經由過程類名挪用靜態成員函數和非靜態成員函數
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
結論1:不克不及經由過程類名來挪用類的非靜態成員函數。
第二個例子,經由過程類的對象挪用靜態成員函數和非靜態成員函數
將上例的main()改成:
void main()
{
Point pt;
pt.init();
pt.output();
}
編譯經由過程。
結論2:類的對象可使用靜態成員函數和非靜態成員函數。
第三個例子,在類的靜態成員函數中應用類的非靜態成員
#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
由於靜態成員函數屬於全部類,在類實例化對象之前就曾經分派空間了,而類的非靜態成員必需在類實例化對象後才有內存空間,所以這個挪用就失足了,就比如沒有聲明一個變量卻提早應用它一樣。
結論3:靜態成員函數中不克不及援用非靜態成員。
第四個例子,在類的非靜態成員函數中應用類的靜態成員
class Point
{
public:
void init()
{
output();
}
static void output()
{
}
};
void main()
{
Point pt;
pt.output();
}
編譯經由過程。
結論4:類的非靜態成員函數可以挪用用靜態成員函數,但反之不克不及。
第五個例子,應用類的靜態成員變量
#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)
這是由於類的靜態成員變量在應用前必需先初始化。
在main()函數前加上int Point::m_nPointCount = 0;
再編譯鏈接無毛病,運轉法式將輸入1。
結論5:類的靜態成員變量必需先初始化再應用。
聯合下面的五個例子,對類的靜態成員變量和成員函數作個總結:
一。靜態成員函數中不克不及挪用非靜態成員。
二。非靜態成員函數中可以挪用靜態成員。由於靜態成員屬於類自己,在類的對象發生之前就曾經存在了,所以在非靜態成員函數中是可以挪用靜態成員的。
三。靜態成員變量應用前必需先初始化(如int MyClass::m_nNumber = 0;),不然會在linker時失足。
再給一個應用類的靜態成員變量和函數的例子以加深懂得,這個例子樹立一個先生類,每一個先生類的對象將構成一個雙向鏈表,用一個靜態成員變量記載這個雙向鏈表的表頭,一個靜態成員函數輸入這個雙向鏈表。
#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);
//樹立雙向鏈表,新數據從鏈表頭部拔出。
this->next = m_head;
this->prev = NULL;
if (m_head != NULL)
m_head->prev = this;
m_head = this;
}
Student::~Student ()//析構進程就是節點的離開進程
{
if (this == m_head) //該節點就是頭節點。
{
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();
}
法式將輸入:
固然在本例還可以增長個靜態成員變量來表現鏈表中先生個數,假如讀者有興致,就將這個作為小演習吧。