18

I am using private inheritance, and I am surprised to see that in the derived class use of any base object is not allowed.

class A;
class B : private A;
class C : public B;

C::method_1()
{
    A* a; // Temporary "A" object for local computation
}

This has nothing to do with inheritance. I don't want to access any this->base method!

This configuration provide a C2247 error in Visual Studio (" 'A' not accessible, because 'B' use 'private' to inherit from 'A' ").

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131

2 Answers2

23

Change this:

A* a;

to this:

::A* a;

since C inherits from B, and B from A, thus you need the scope resolution operator to do the trick.

Instead of starting at the local scope which includes the class parents, ::A starts looking at the global scope because of the ::.

From the Standard:

11.1.5 Acess Specifiers

In a derived class, the lookup of a base class name will find the injected-class-name instead of the name of the base class in the scope in which it was declared. The injected-class-name might be less accessible than the name of the base class in the scope in which it was declared.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • I don't really understand the meanning of the scope operator in that case but it works fine. Thank you ! – Guillaume Despine Nov 28 '17 at 09:47
  • 1
    @GuillaumeDespine: Instead of starting at the local scope which includes the class parents, `::A` starts looking at the global scope because of the `::`. – Zan Lynx Nov 28 '17 at 09:48
  • 1
    ISO : 11.1 Access Specifiers: [Note: In a derived class, the lookup of a base class name will find the injected-class-name instead of the nameofthebaseclassinthescopeinwhichitwasdeclared. Theinjected-class-namemightbelessaccessible than the name of the base class in the scope in which it was declared. —end note] Has same example – Mihayl Nov 28 '17 at 09:52
15

ISO C++: 11.1 Access Specifiers

5 [Note: In a derived class, the lookup of a base class name will find the injected-class-name instead of the name of the base class in the scope in which it was declared. The injected-class-name might be less accessible than the name of the base class in the scope in which it was declared. —end note]

And the example from the standard:

class A { };
class B : private A { };
class C : public B {
    A* p; // error: injected-class-name A is inaccessible
   ::A* q; // OK 
};

N3797 Working Draft, Standard for Programming Language C++

Mihayl
  • 3,821
  • 2
  • 13
  • 32