C++ 中的私有继承 visibility/access
Private inheritance visibility/access in C++
为什么接口由于私有继承而在方法中具有特殊的可见性?
请注意,在我的派生 class 中需要全局说明符 ::。
我不明白为什么一个方法会由于私有继承而继承某种可见性。 Derived class 无法访问 Control 是完全合理的。但是为什么它也不能通过会员访问呢?
class Control
{
public:
void ModifySomething();
};
class Base : private Control
{
private:
virtual void Update( Control& i_control );
};
class Derived : public Base
{
private:
// ----------↓↓
void Update( ::Control& i_control ) override;
};
注意:我知道我们可以通过组合来解决这个问题。但我想知道为什么它在 C++ 中是这样定义的。我们可以打破 const-ness 什么的吗?
class Derived
无法访问 class Base
中的任何内容 private
,因此它无法通过 Base
访问 class Control
。但是,它可以直接访问 Control
,因为它是在与 Derived
.
相同的全局范围内声明的
正如@formerlyknownas_463035818评论的那样,有两条从Derived
到Control
的路径,但一条由于private
访问控制而被阻止,所以另一条是全局路径,被选中。
根据 C++ 17 标准(14.1 访问说明符)
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 ]
并且有一个类似于您的代码片段的示例。
[Example:
class A { };
class B : private A { };
class C : public B {
A* p; // error: injected-class-name A is inaccessible
::A* q; // OK
};
— end example ]
这是在派生的 class 定义中注入的 class 私有基 class 的名称隐藏了命名空间中定义的基 class 的名称。并且这个注入的名字是私有的。所以派生的 class 没有访问这个私有注入名称的权限。
为什么接口由于私有继承而在方法中具有特殊的可见性?
请注意,在我的派生 class 中需要全局说明符 ::。
我不明白为什么一个方法会由于私有继承而继承某种可见性。 Derived class 无法访问 Control 是完全合理的。但是为什么它也不能通过会员访问呢?
class Control
{
public:
void ModifySomething();
};
class Base : private Control
{
private:
virtual void Update( Control& i_control );
};
class Derived : public Base
{
private:
// ----------↓↓
void Update( ::Control& i_control ) override;
};
注意:我知道我们可以通过组合来解决这个问题。但我想知道为什么它在 C++ 中是这样定义的。我们可以打破 const-ness 什么的吗?
class Derived
无法访问 class Base
中的任何内容 private
,因此它无法通过 Base
访问 class Control
。但是,它可以直接访问 Control
,因为它是在与 Derived
.
正如@formerlyknownas_463035818评论的那样,有两条从Derived
到Control
的路径,但一条由于private
访问控制而被阻止,所以另一条是全局路径,被选中。
根据 C++ 17 标准(14.1 访问说明符)
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 ]
并且有一个类似于您的代码片段的示例。
[Example:
class A { };
class B : private A { };
class C : public B {
A* p; // error: injected-class-name A is inaccessible
::A* q; // OK
};
— end example ]
这是在派生的 class 定义中注入的 class 私有基 class 的名称隐藏了命名空间中定义的基 class 的名称。并且这个注入的名字是私有的。所以派生的 class 没有访问这个私有注入名称的权限。