1

I thought the private members don't even exist outside of the class scope, so we just can't access them. But consider:

#include <iostream>

class A
{
private:
    static const int a = 1;
};

const int A::a; //Access to the private member outside the class scope
                //the compiler doesn't compain

int main ()
{
    std::cout << A::a << std::endl; //compile-time error
}

Why is it permitted? Is it just for convinience?

St.Antario
  • 26,175
  • 41
  • 130
  • 318
  • This is pretty much the [same question](http://stackoverflow.com/questions/30929941/definition-of-the-static-data-member/30929971?noredirect=1#comment49895847_30929971) you just asked. You can define a `static` member outside the class because that is the **only** way to define a `static` member. You can't do this with a non-static member. – user657267 Jun 19 '15 at 05:06
  • That's just how you provide a definition for a static data member. If you had to provide the definition within the body of the class, then that class definition could only appear in a single translation unit, or else it would violate ODR. Such a restriction would make that class pretty much useless, wouldn't it? – Praetorian Jun 19 '15 at 05:13

2 Answers2

8

It is permitted because the language standard says so.

The concept of member access control implemented with the help of access specifiers like private has absolutely nothing to do with imposing restrictions on member definitions. It was introduced for completely different purposes. It is intended to restrict access in completely different contexts. Language specification does not prohibit defining private members outside of the class. Why would it?

Your description of private members as "not even existing" outside of class scope is completely incorrect. The language standard actually says explicitly that protected and private members of the class are perfectly visible from outside of the class and even found by the name lookup. Access restrictions are checked only after that.

E.g. in a piece of code like the following

struct S {
    void foo(long);
private:
    void foo(int);
};

int main() {
    S().foo(1);
}

the compiler is required to see the private S::foo(int) from outside, choose it through overload resolution and only then tell you that you are attempting to call a private function.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
1
#include <iostream>

class A
{
private:
    /* an in-class initialization, which is only allowed if the
     * data member is static const and is of integral type.
     */
    static const int a = 1;
};

const int A::a; // a definition, not an "access".
/* The above line will actually incur a "duplicate initialization"
 * compile-time error, because the data member a has already been
 * defined in the class.
 */

int main ()
{
    std::cout << A::a << std::endl; // compile-time error
}
Cody
  • 609
  • 4
  • 21