C++ 访问基类的受保护构造函数
派生类可以在其ctor初始值设定项中调用受保护的基类构造函数,但只能为其自己的基类子对象调用,而不能在其他地方调用:C++ 访问基类的受保护构造函数,c++,oop,language-lawyer,C++,Oop,Language Lawyer,派生类可以在其ctor初始值设定项中调用受保护的基类构造函数,但只能为其自己的基类子对象调用,而不能在其他地方调用: class Base { protected: Base() {} }; class Derived : Base { Base b; public: Derived(): Base(), // OK b() { // error Base b2; // error
class Base {
protected:
Base() {}
};
class Derived : Base {
Base b;
public:
Derived(): Base(), // OK
b() { // error
Base b2; // error
}
};
标准对此有何规定?下面是[class.protected]/1:
当出现非静态数据时,应用第11条前面描述的访问检查之外的附加访问检查
成员或非静态成员函数是其命名类(11.2)的受保护成员,如前所述
早些时候,授予对受保护成员的访问权,因为引用发生在某个成员的朋友或成员中
类C
。如果访问要形成指向成员的指针(5.3.1),嵌套名称说明符应表示C
或a
从C
派生的类。所有其他访问都涉及(可能是隐式的)对象表达式(5.2.5)。在这种情况下,,
对象表达式的类应为C
或派生自C
的类。[举例:…]
调用构造函数时是否涉及对象表达式?没有,是吗?那么标准中描述了受保护基类构造函数的访问控制在哪里?受保护的访问仅适用于您自己当前对象类型的父成员。您无法获得对其他受保护成员的公共访问权限r父类型的对象。在您的示例中,您只能作为
派生
的一部分访问默认的基本构造函数,而不是作为b
的独立对象
让我们将您从标准(11.4/1)中发布的报价细分。我们将假设标准中的C
对应于您的派生类:
除第11条前面所述之外的额外访问检查
当非静态数据成员或非静态成员函数
是其命名类(11.2)的受保护成员
因此,基类构造函数实际上是其命名类(B
)的非静态成员函数,因此本条款适用于目前为止
如前所述,授予对受保护成员的访问权是因为
引用发生在某个C类的朋友或成员中
C
的成员(构造函数),所以我们在这里仍然很好
如果访问要形成指向成员(5.3.1)的指针,则
嵌套名称说明符应表示C或从C派生的类
这不是指向成员的指针,因此不适用
所有其他访问都涉及(可能是隐式的)对象表达式
(5.2.5)
然后,该标准断言所有其他可能的访问必须涉及对象表达式
在这种情况下,对象表达式的类应为C或a类
源于C
最后,标准规定表达式的类必须是C
或进一步的派生类。在这种情况下,表达式Base()
实际上是一个C
,调用父构造函数(将其视为this->Base()
。表达式b
的类型显然是Base
(这是明确声明的成员b
,想想this->b->Base()
“
当在类N
中命名时,成员m
可在点R处访问,如果
m
作为N
的成员是公开的,或者
m
作为N
的成员是私有的,而R出现在类N
的成员或朋友中,或
m
作为N
的成员受到保护,而R出现在类N
的成员或朋友中,
或者在类的成员或朋友中P
来自N
,其中m
作为P
的成员是公共的、私有的或受保护的,或者
- 存在一个
N
的基类B
,该基类可在R处访问,
当在类B
中命名时,可以在R处访问m
用于构造函数调用
Base b2;
上述第三点适用。m
是Base
构造函数。N
命名类是Base
m
,因为Base
的成员受到保护,声明发生在派生自Base
的类的成员中,但Base不是这种情况de>构造函数作为派生的
的成员是公共的、私有的或受保护的:它不是派生的
的成员,构造函数不是隐式继承的
我认为“是公共的、私人的或受保护的”这句话相当尴尬;我只能猜测这是这一段演变的结果
我还没有找到一个解释,说明受保护的Base
构造函数是如何在Derived
中的成员初始值设定项列表中访问的,但是我刚刚开始研究这个问题
更新:我在初始化列表中找不到与访问构造函数相关的标准语言,也找不到任何关于它的缺陷报告。这很可能是一个缺陷。我看到了,但在标准中这是在哪里指定的?@Brian:你应该将该注释移到问题上。否则问题是重复的。@Cheersandhth.-Alf问题是“标准对此有何规定”,但我还是对其进行了编辑以重申。相关/重复:有趣的是,构造函数应该没有名称[class.ctor],访问控制不应该应用于它们;)(以及名称查找)@dyp,我认为OP了解这一行为。他正在标准中寻找证据,清楚地解释这一行为。你发布的链接没有任何答案指向任何相关的地方