Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

A derived class can call a protected base class constructor in its ctor-initializer, but only for its own base class subobject, and not elsewhere:

class Base {
  protected:
    Base() {}
};

class Derived : Base {
  Base b;
  public:
    Derived(): Base(),    // OK
               b() {      // error
        Base b2;          // error
    }
};

What does the standard say about this? Here is [class.protected]/1:

An additional access check beyond those described earlier in Clause 11 is applied when a non-static data member or non-static member function is a protected member of its naming class (11.2) 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), the nested-name-specifier shall denote C or a class derived from C. 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. [ Example: ...

Is there an object expression involved when calling a constructor? There isn't, is there? So where in the standard is access control for protected base class constructors described?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
701 views
Welcome To Ask or Share your Answers For Others

1 Answer

C++11 §11.2/5:


A member m is accessible at the point R when named in class N if

  • m as a member of N is public, or

  • m as a member of N is private, and R occurs in a member or friend of class N, or

  • m as a member of N is protected, and R occurs in a member or friend of class N, or in a member or friend of a class P derived from N, where m as a member of P is public, private, or protected, or

  • there exists a base class B of N that is accessible at R, and m is accessible at R when named in class B.

For your constructor invocation

Base b2;

the 3rd point above applies. m is the Base constructor. N, the naming class, is Base. m as a member of Base is protected, and the declaration occurs in a member of class Derived derived from Base, but it's not the case that the Base constructor as a member of Derived is public, private or protected: it’s simply not a member of Derived, constructors are not implicitly inherited.

I think the language “is public, private, or protected” is pretty awkward; I can only surmise that it’s the result of some evolution of this paragraph.

I have yet to find an explanation of how formally the protected Base constructor is accessible in a member initializer list in Derived, but then I just started looking at this for this question.


Update: I fail to find any language in the standard pertaining to access to constructors in an initializer list, and I fail to find any Defect Report about it. It’s quite possibly a defect.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...