访问基类的受保护构造函数 [英] Access to protected constructor of base class

查看:99
本文介绍了访问基类的受保护构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

派生类可以在其 ctor-initializer 中调用受保护的基类构造函数,但只能为自己的基类子对象,而不是其他位置:

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
    }
};

这个标准说的是什么?这里是[class.protected] / 1:

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


除非第11章中描述的附加访问检查, data
成员或非静态成员函数是其命名类的受保护成员(11.2)如早前描述的
,授予对受保护成员的访问权,因为引用发生在某个$的朋友或成员中b $ b class C 。如果访问是形成指向成员的指针(5.3.1),则 nested-name-specifier 应表示 C 或a
类派生自 C 。所有其他访问涉及一个(可能是隐式)对象表达式(5.2.5)。在这种情况下,
对象表达式的类应为 C 或从 C 派生的类。 [示例: ...

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?

推荐答案

protected 访问权限仅适用于您自己当前对象类型的父成员 。您无法公开访问父类型的其他对象的受保护成员。在你的例子中,你只能访问默认基础结构作为 Derived 的一部分,而不是当它是一个独立的对象 b

The protected access only applies to parent members of your own current object type. You don't get public access to the protected members of other objects of the parent type. In your example you only get access to the default base contructor as part of a Derived, not when it's a standalone object as b.

让我们分解您从标准发布的报价(11.4 / 1)。我们假设标准中的 C 对应于您的 Derived 类:

Let's break down the quote you posted from the standard (11.4/1). We'll assume that C in the standard corresponds to your Derived class:


当非静态数据成员或非静态成员函数
是受保护的数据成员或非静态成员函数时,应用除了前面第11节所述的附加访问检查

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).

因此,基类构造函数实际上是一个非静态成员

So the base class constructor is effectively a non-static member function of its naming class (B) here, so this clause applies so far.

如前所述,授予对受保护成员的访问权限,因为
引用发生在某个类C的朋友或成员中。

As described earlier, access to a protected member is granted because the reference occurs in a friend or member of some class C.

C 的成员(构造函数),因此我们在这里仍然很好。

Member (constructor) of C so we're still good here.


如果访问是形成指向成员的指针(5.3.1),
nested-name-specifier应该表示C或从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.

这不是指向成员的指针,因此不适用。

This is not a pointer to member so this doesn't apply.


所有其他访问涉及一个(可能隐式)对象表达式
(5.2.5)。

All other accesses involve a (possibly implicit) object expression (5.2.5).


b $ b

标准然后断言所有其他可能的访问必须涉及一个对象表达式。

The standard then asserts that all other possible accesses must involve an object expression.


在这种情况下,对象表达式应为C或从C派生的类

In this case, the class of the object expression shall be C or a class derived from C.

最后,标准声明表达式的类必须 C 或另一个派生类。在这种情况下,你的表达式 Base()实际上是一个 C ,调用父构造函数code> this-> Base()。表达式 b 显然是类型 Base (这是成员 b 的显式声明类型,考虑 this-> b-> Base())现在我们做检查: Base a C > C ?不是,因此代码不合法​​。

Finally the standard states that the class of the expression must be C or a further derived class. In this case your expression Base() is in fact a C, calling the parent constructor (think about it as this->Base(). The expression b is clearly of type Base (that's the explicitly declared type of the member b, think about this->b->Base()). Now we do the check: Is Base a C or child of C? It is not, so the code is not legal.

这篇关于访问基类的受保护构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆