2014-09-24 132 views
3

我想了解靜態成員多一點,我一直在嘗試使用代碼片段來查看哪些方法合法,哪些不合法。通過對象實例訪問私有靜態成員

我的理解是,靜態變量不駐留在類/結構中,但是是分開的。換句話說,下面代碼中的變量y應該被A::y而不是this->y訪問,因此我的假設是下面的代碼不會被編譯。 (MingGW),我很驚訝。

有人可以解釋這種訪問機制是如何工作和實施的。

// ClassA.h 
class A{ 
    private: 
    int x; 
    static int y; 
    public: 
    void setX(int x){this->x = x;} 
    void setY(int y){this->y = y;} 
} 

// main.cpp 
#include "ClassA.h" 

int main (int argc,char* argv[]){ 
    A my_A; 
    my_A.setX(5); 
    my_A.setY(10); 
    return 0; 
} 
+0

靜態變量確實存在於類中(它們屬於類本身)。並且仍然可以通過類成員訪問運算符來訪問靜態成員。 – 0x499602D2 2014-09-24 01:22:44

+0

編譯代碼時爲什麼會出現錯誤? 克++ -o測試的main.cpp '/tmp/cciEVrgm.o:在函數 'A :: SETY(INT)': main.cpp中:(text._ZN1A4setYEi [_ZN1A4setYEi] + 0×10):未定義參考'A :: y' collect2:錯誤:ld返回1退出狀態' – 2014-09-24 01:25:22

+0

爲了簡單起見,我沒有添加靜態成員'y'定義。對於那個很抱歉。 – 2014-09-24 01:28:21

回答

7

這是可行的,因爲語言允許。 this指針僅用於此上下文中的類型;當發現該成員是靜態的時,指針將不會被使用。也就是說,編譯後的代碼根本不會使用指針。

因此這兩者相當於,儘管編譯器可能會發出警告。您應該更喜歡使用類型名稱來訪問靜態成員,因爲它更好地表示實際發生的事情,因此它更加清晰。

進一步閱讀:Accessing static members via an instance(包含當該技術可能是有用的一些例子)


這並不總是當指針或對象是與副作用的表達的情況。例如,假設下面的代碼:

#include <iostream> 

class Foo { 
public: 
    static int x; 
}; 

int Foo::x = 0; 

Foo aFoo; 

Foo & test() { 
    std::cout << "test()" << std::endl; 
    return aFoo; 
} 

int main(void) { 
    test().x = 1; 

    return 0; 
} 

編譯器知道在編譯時間,其中test().x是,因爲它知道test()返回到Foo參考,並Foo::x是靜態的 - 但即使編譯器知道在哪裏找到test().x而實際上並沒有發現評估test()的代碼,但它仍然發出函數調用,並簡單地忽略了結果,因爲替代方法(根本不打電話)可能更令人困惑。

在此示例中,test().x = 1;相當於(test(), Foo::x = 1);

0

Can someone please explain how this access mechanism works

所有編譯器需要的是指針變量的類型,它知道它。其實際值將被忽略,即使它爲空。

and is implemented

這兩個例子都編譯成相同的代碼。