c++類中靜態函數不能調用類中的非靜態函數原因

程序最終都將在內存中執行,變量只有在內存中佔有一席之地時才能被訪問。
 類的靜態成員(變量和方法)屬於類本身,在類加載的時候就會分配內存,可以通過類名直接去訪問;
非靜態成員(變量和方法)屬於類的對象,所以只有在類的對象產生(創建類的實例)時纔會分配內存,然後通過類的對象(實例)去訪問。 
  在一個類的靜態成員中去訪問其非靜態成員之所以會出錯是因爲在類的非靜態成員不存在的時候類的靜態成員就已經存在了,訪問一個內存中不存在的東西當然會出錯:
class CA{
private:
    int a;     //非靜態成員,創建類的實例時分配內存,類的不同實例對應不同的內存區域  
    static int b;     //靜態成員,類加載時分配內存,類的所有實例共享   
public:
    void fa(void)
{
        a = 1;
        b = 1;
 }       static void fb(void){
        //a = 1;        //Non-static member can't be accessed by static function
        b = 1;
    }
};

int CA::b = 1;   
int main(void)
{
    
    CA ca;
    ca.fa();
    CA::fb();
 return 0;
}
   類的靜態函數和普通函數的最大區別就是 :
    (1)類的靜態函數依賴類存在
     (2)普通類的成員函數 依賴對象存在 普通類的成員函數有個this指針指向當前對象
而靜態函數沒有此指針
因爲它們在內存中放置的位置不同。 類的靜態函數放置在靜態區。而類的普通函數在函數內而存在。 類的靜態函數可以通過函數名::靜態函數 直接引用。而類的普通函數不可以 類的靜態函數不能直接調用類的成員變量,但是能調用類的靜態的成員變量。 類的普通函數可以直接調用類的成員函數,也可以調用類的靜態成員變量,它是依賴對象存在的。

程序最終都將在內存中執行,變量只有在內存中佔有一席之地時才能被訪問。

類的靜態成員(變量和方法)屬於類本身,在類加載的時候就會分配內存,可以通過類名直接去訪問;非靜態成員(變量和方法)屬於類的對象,所以只有在類的對象產生(創建類的實例)時纔會分配內存,然後通過類的對象(實例)去訪問。

在一個類的靜態成員中去訪問其非靜態成員之所以會出錯是因爲在類的非靜態成員不存在的時候類的靜態成員就已經存在了,訪問一個內存中不存在的東西當然會出錯。

C++會區分兩種類型的成員函數:靜態成員函數和非靜態成員函數。這兩者之間的一個重大區別是,靜態成員函數不接受隱含的this自變量。所以,它就無法訪問自己類的非靜態成員。

 

靜態數據成員

    在類中,靜態成員可以實現多個對象之間的數據共享,並且使用靜態數據成員還不會破壞隱藏的原則,即保證了安全性。因此,靜態成員是類的所有對象中共享的成員,而不是某個對象的成員。

    使用靜態數據成員可以節省內存,因爲它是所有對象所公有的,因此,對多個對象來說,靜態數據成員只存儲一處,供所有對象共用。靜態數據成員的值對每個對象都是一樣,但它的值是可以更新的。只要對靜態數據成員的值更新一次,保證所有對象存取更新後的相同的值,這樣可以提高時間效率。

靜態數據成員的使用方法和注意事項如下:

1、靜態數據成員在定義或說明時前面加關鍵字static。

2、靜態成員初始化與一般數據成員初始化不同。靜態數據成員初始化的格式如下:
     <數據類型><類名>::<靜態數據成員名>=<值>

這表明:
(1) 初始化在類體外進行,而前面不加static,以免與一般靜態變量或對象相混淆。

(2) 初始化時不加該成員的訪問權限控制符private,public等。

(3) 初始化時使用作用域運算符來標明它所屬類,因此,靜態數據成員是類的成員,而不是對象的成員。

3、靜態數據成員是靜態存儲的,它是靜態生存期,必須對它進行初始化。

4、引用靜態數據成員時,採用如下格式:

<類名>::<靜態成員名>

 

靜態成員函數

    靜態成員函數和靜態數據成員一樣,它們都屬於類的靜態成員,它們都不是對象成員。因此,對靜態成員的引用不需要用對象名。

在靜態成員函數的實現中不能直接引用類中說明的非靜態成員,可以引用類中說明的靜態成員。如果靜態成員函數中要引用非靜態成員時,可通過對象來引用。
下面通過例子來說明這一點。

#include <iostream>

using namespace std;

 

class M

{

public:

     M(int a) { A=a; B+=a;}

     static void f1(M m);

private:

     int A;

     static int B;

};

 

void M::f1(M m)

{

     cout<<"A="<<m.A<<endl; //靜態成員函數中通過對象來引用非靜態成員

     cout<<"B="<<B<<endl;

}

 

int M::B=0; //靜態數據成員初始化的格式<數據類型><類名>::<靜態數據成員名>=<值>

void main()

{

     M P(5),Q(10);

     M::f1(P); //靜態成員函數調用時不用對象名

     M::f1(Q);

}



讀者可以自行分析其結果。從中可看出,調用靜態成員函數使用如下格式:

<類名>::<靜態成員函數名>(<參數表>);

 

運行結果:

A=5

B=15

A=10

B=15


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章