static作用,靜態成員變量和靜態成員函數


static關鍵字有倆作用:(1).控制存儲分配;(2).控制一個名字的可見性和連接。
 
隨着C++ 名字空間 的引入,我們有了更好的,更靈活的方法來控制一個大項目的名字增長。
 
 
在類的內部使用 static 是在全程序中 控制名字 的另一種方法。這些名字不會與全局名沖突,並且 可見性和訪問 也限制在程序內部,使得在維護代碼時有更多的控制。

 

數據成員可以分靜態變量、非靜態變量兩種.
  靜態成員:靜態類中的成員加入static修飾符,即是靜態成員.可以直接使用類名+靜態成員名訪問此靜態成員,因為靜態成員存在於內存,非靜態成員需要實例化才會分配內存,所以靜態成員不能訪問非靜態的成員..因為靜態成員存在於內存,所以非靜態成員可以直接訪問類中靜態的成員.

  非成靜態員:所有沒有加Static的成員都是非靜態成員,當類被實例化之后,可以通過實例化的類名進行訪問。非靜態成員的生存期決定於該類的生存期..而靜態成員則不存在生存期的概念,因為靜態成員始終駐留在內容中。

一個類中也可以包含靜態成員和非靜態成員,類中也包括靜態構造函數和非靜態構造函數。

 

在C++中,靜態成員是屬於整個類的而不是某個對象,靜態成員變量只存儲一份供所有對象共用。所以在所有對象中都可以共享它。使用靜態成員變量實現多個對象之間的數據共享不會破壞隱藏的原則,保證了安全性還可以節省內存。
靜態成員的定義或聲明要加個關鍵static。靜態成員可以通過雙冒號來使用即<類名>::<靜態成員名>

class Point  
{  
public:   
    void init()  
    {    
    }  
    static void output()  
    {  
    }  
};  
int main(void)  
{  
    Point::init();  
    Point::output();  
}  

  

編譯出錯:error C2352: 'Point::init' : illegal call of non-static member function
結論1:不能通過類名來調用類的非靜態成員函數。

通過類的對象調用靜態成員函數和非靜態成員函數

int main(void) 
{ 
    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; }; int 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()  
	{  
	}  
};  
int main()  
{  
	Point pt;  
	pt.output(); 
	return 0; 
}  

編譯通過。
結論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;  
};  
int main()  
{  
	Point pt;  
	pt.output(); 
	return 0; 
}  

編譯無錯誤,生成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時出錯。

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM