Search code examples
c++constructorprotectedradixderived

Create base class instance in derived class member function when the base class constructor is protected


Given the following code:

class A
{
protected:
    A(){};  // compilation error
public:
    void foo(){cout << "A\n";}; 
};

class B : public A
{
public:
    B() { };
    void foo(){
        cout << "B\n";
        A A(); // OK
        A a1; // compilation error
    }
};

If I changed the base class A constructor to public, the code compiles. How to explain this?


Solution

  • §11.4/1:

    As described earlier, access to a protected member is granted because the reference occurs in a friend or member of some class C. If the access is to form a pointer to member (5.3.1), […].
    All other accesses involve a (possibly implicit) object expression (5.2.5). In this case, the class of the object expression shall be C or a class derived from C.

    In your case, the access is implicit but nonetheless present. We are trying to access As constructor with the (implicit) object argument a1. §11/6:

    All access controls in Clause 11 affect the ability to access a class member name from the declaration of a particular entity […]. [ Note: this access also applies to implicit references to constructors, conversion functions, and destructors.end note ]

    However, a1 is not of type B or a class derived from B. Hence our above requirement is not met, and access control is not happy.