2

In the following example (taken from here) we have a private static variable x and then we change its name outside of the class. What confuses me is why is it allowed to change a private variable outside of the class? What is then the reason to declare it a private.

// static_member_functions.cpp
#include <stdio.h>

class StaticTest
{
private:
    static int x;
public:
    static int count()
    {
        return x;
    }
};

int StaticTest::x = 9;

int main()
{
    printf_s("%d\n", StaticTest::count());
}
Roman
  • 124,451
  • 167
  • 349
  • 456
  • I answered myself exactly the same question in this post. Thanks you very much! – Maf Mar 22 '21 at 16:07

3 Answers3

4

This is not "changing the variable", it's defining it.

Every static member must be defined outside the class (static int x; is just a declaration; if you remove int StaticTest::x = 9; there will be a linker error saying something like "undefined reference to StaticTest::x").


Try changing it in the main, for example:

StaticTest::x = 13;

and you'll get the error, you expected (error: ‘int StaticTest::x’ is private).

Kiril Kirov
  • 37,467
  • 22
  • 115
  • 187
  • by defining do you mean initializing it? its definition is in the class – QuantumKarl Apr 10 '13 at 09:46
  • @QuantumKarl - no, by "defining" I mean "defining", not "initializing". This is an "exception" for the `static` members. See http://stackoverflow.com/questions/3536372/defining-static-members-in-c (the second answer) for more detailed information. – Kiril Kirov Apr 10 '13 at 10:10
  • @QuantumKarl - the class **definition** contains a **declaration** of the static data member. You also have to **define** the static data member, and that has to be done outside the class definition. – Pete Becker Apr 10 '13 at 14:43
  • @Pete Becker + Kiril kirov thanks for clarifying the difference. I don't use static variables much. at uni I was taught to try avoid them. Any idea why? – QuantumKarl Apr 11 '13 at 08:42
  • @QuantumKarl - depends on the needs. Sometimes `static` is your only (or the best) option. The most significant difference is, that a `static` member is shared between _all_ instances of the class. In this case, if you have 10 objects `StaticTest`, all of them will share the same `x`. – Kiril Kirov Apr 11 '13 at 08:45
  • I answered myself exactly the same question in this post. Thank sfor the answer. – Maf Mar 22 '21 at 16:07
0

The variable is not changed outside the class.

Consider this slightly modified example:

class StaticTest
{
    private:
        static int x;

    public:
        static int count();
};

int StaticTest::x = 9;

int StaticTest::count()
{
    return x;
}

Neither is x initialized "outside the class*, nor is it accessed outside of it. The class { } block merely declares the class members. The StaticTest:: scope qualifier tells the compiler that the subsequent definitions of x and count() are part of the StaticTest class.

Try accessing x from your main():

int main()
{
    printf_s("%d\n", StaticTest::x);
}

You will see that it is not possible, since x is private.

This is done so that you can seperate the declaration (in the .hpp header file) from the implementation (in the .cpp implementation file). (This breaks once you start using templates, but nothing is perfect.)

DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • I cannot compile your first example. `static int StaticTest::count()` cannot be declared. – Roman Apr 10 '13 at 08:21
  • @Roman: Sorry. No `static` at point of definition. (The same as for `x`, by the way.) This is not related to the point of my answer. – DevSolar Apr 10 '13 at 08:25
0

Access control doesn't affect visibility: private members of a class are visible everywhere, regardless of whether they are static or not.

Access control affects "access" (not visibility) to names or symbols, not to the entities they manage, and it affects access to all names, regardless of what they name. Because access control doesn't affect visibility, name lookup will find the names, but if you don't have access, it will be an error (even if there is an entity with the same name to which you do have access).

With regards to your example, I don't understand the problem. The only access to StaticTest::x is in the member function StaticTest::count(). Why should this be a problem?

James Kanze
  • 150,581
  • 18
  • 184
  • 329