Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing private static member through an object instance

Tags:

c++

this

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;
}
like image 306
Fady Megally Avatar asked Aug 08 '26 22:08

Fady Megally


1 Answers

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 equivalent1, 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);.

like image 136
cdhowie Avatar answered Aug 10 '26 11:08

cdhowie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!