Accessing a private static member through an object instance

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

I understand that a static variable is not inside a class / struct, but is separate. In other words, the variable y

in the code below should be accessed A::y

, not this->y

, so my assumption was that the code below would not compile. I was surprised this happened (MingGW).

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

// ClassA.h
class A{
    int x;
    static int y;
    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;
  return 0;



source to share

2 answers

It works because the language allows it. A pointer this

is only used for its type in this context; when the element is found to be static, the pointer will not be used. That is, the compiled code will not use the pointer at all.

Thus, two are equivalent to 1, although compilers may issue warnings about this. You should use type names to access static members because they better represent what is really going on and therefore is more understandable.

Further Reading: Accessing Static Members Through an Instance (contains some examples of when this method can be useful)

1 This is not always the case when the pointer or object is a side-effect expression. For example, given the following code:

#include <iostream>

class Foo {
    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 it test().x

is because it knows what is test()

returning a reference to Foo

and Foo::x

is static - but even if the compiler knows where to find it test().x

without actually emitting code that evaluates the value test()

, it still emits a function call and just ignores the result because the alternative (not making the call at all) would be even more confusing.

In this example, it is test().x = 1;

equivalent (test(), Foo::x = 1);




Can someone explain how this access mechanism works.

All the compiler needs is the type of pointer it knows. Its actual value is ignored even if it is zero.

and implemented

Both of your examples will compile with the same code.



All Articles