简体   繁体   中英

Accessing private static member through an object instance

I'm trying to understand static members a little bit more and I've been experimenting with snippets of code to see what works/is legal and what is not.

My understanding is that static variable do not reside inside the class/struct but are separate. In other words,the variable y in the code below should be accessed by A::y and not this->y , hence my assumption was that code below would not compile. I was surprised that it did (MingGW).

Can someone please explain how this access mechanism works and is implemented.

// 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;
}

This works because the language allows it. The this pointer is only used for its type in this context; when the member is discovered to be static, the pointer won't be used. That is to say, the compiled code will not use the pointer at all.

The two are therefore equivalent 1 , though compilers may issue warnings about this. You should prefer using type names to access static members because it better represents what is actually happening, and therefore it is more clear.

Further reading: Accessing static members via an instance (contains some examples of when this technique can be useful)


1 This isn't always the case when the pointer or object is an expression with side-effects. For example, given the following code:

#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;
}

The compiler knows at compile time where test().x is, because it knows that test() returns a reference to a Foo , and Foo::x is static -- but even though the compiler knows where to find test().x without actually emitting code that evaluates test() it still emits the function call and simply ignores the result, because the alternative (not making the call at all) is likely to be even more confusing.

In this sample, test().x = 1; is equivalent to (test(), Foo::x = 1); .

Can someone please explain how this access mechanism works

All the compiler needs is the type of the pointer variable, which it knows. Its actual value is ignored, even if it's null.

and is implemented

Both your examples compile to the same code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM