2014-09-24 82 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

这两个例子都编译成相同的代码。