11

I'm learning C++. The documentation learn.microsoft.com/en-us/cpp/cpp/member-access-control-cpp says:

When you specify a base class as private, it affects only nonstatic members. Public static members are still accessible in the derived classes.

However, the following code slightly adjusted from the example following the previous quote cause error C2247:

'Base::y' not accessible because 'Derived1' uses 'private' to inherit from 'Base'.

I will appreciate any help with this situation.

class Base
{
public:
    int x;             
    static int y;      
};

class Derived1 : private Base
{
};

class Derived2 : public Derived1
{
public:
    int ShowCount();    
};

int Derived2::ShowCount()
{
    int cCount = Base::y;       
    return cCount;
}
gsamaras
  • 71,951
  • 46
  • 188
  • 305
KarlEL
  • 131
  • 6

2 Answers2

16

That documentation is a little misleading.

The correct compiler behaviour is for Base::y and Base::x to both be inaccessible in Derived, if you use that notation to attempt to reach the static member.

But you can reach it via the global namespace (thereby circumventing Derived1) by using another scope resolution operator:

int Derived2::ShowCount()
{
    int cCount = ::Base::y;       
    return cCount;
}

Finally, don't forget to define y somewhere if you want the link stage to be successful.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • 4
    The path-finding of the name lookup rules is very frustrating at times. – StoryTeller - Unslander Monica Nov 27 '17 at 09:02
  • 1
    @Bathsheba Could you also please add explanation regarding why adding another scope resolution works in above example. It would be very helpful for me. Thanks! – Pravar Jawalekar Nov 27 '17 at 09:47
  • 1
    @PravarJawalekar: I've added that. Informally, if you go via the *global namespace*, then you reach `Base` directly rather than going via `Derived1`. – Bathsheba Nov 27 '17 at 09:54
  • I've always told people that visibility and accessibility are completely orthogonal. Guess, I'll have to eat crow thanks to another obscure corner case… – Arne Vogel Nov 27 '17 at 11:17
  • Dear @Bathsheba: Thank you very much for your kind and detailed reply. Sorry to bother you again. If `::Base` circumvent `Derived1`, why `::Base::x` does not work? Suppose that we have an `Derived2` object `d2`, is the `Base` which we access via `::Base` the base class subobject in `d2`? – KarlEL Nov 30 '17 at 12:07
  • @KarlEL You need an *instance* of `Base` to access `x`, as the latter is a non-`static` member. – Bathsheba Nov 30 '17 at 12:29
2

Change this:

Base::y;

to this;

::Base::y;
gsamaras
  • 71,951
  • 46
  • 188
  • 305