【问题标题】:Accessing public static members of a base class specified as private访问指定为私有的基类的公共静态成员
【发布时间】:2024-04-24 08:55:01
【问题描述】:

我正在学习 C++。文档docs.microsoft.com/en-us/cpp/cpp/member-access-control-cpp 说:

当您将基类指定为私有时,它只影响非静态成员。公共静态成员仍然可以在派生类中访问。

但是,下面的代码对前面引用的示例稍作调整,导致错误 C2247:

'Base::y' 不可访问,因为'Derived1' 使用'private' 从'Base' 继承。

对于这种情况,我将不胜感激。

class Base
{
public:
    int x;             
    static int y;      
};

class Derived1 : private Base
{
};

class Derived2 : public Derived1
{
public:
    int ShowCount();    
};

int Derived2::ShowCount()
{
    int cCount = Base::y;       
    return cCount;
}

【问题讨论】:

  • 使用::Base::y 获得正确的范围。
  • 我认为微软的例子被打破了。

标签: c++ oop static-members derived-class


【解决方案1】:

该文档有点误导。

正确的编译器行为是,如果您使用该符号尝试到达 @ 987654324@会员。

但是您可以通过全局命名空间使用另一个范围解析运算符(从而绕过Derived1)访问它:

int Derived2::ShowCount()
{
    int cCount = ::Base::y;       
    return cCount;
}

最后,如果您希望链接阶段成功,请不要忘记在某处定义 y

【讨论】:

  • 名称查找规则的寻路有时非常令人沮丧。
  • @Bathsheba 您能否还请添加解释,说明为什么在上面的示例中添加另一个范围解析有效。这对我很有帮助。谢谢!
  • @PravarJawalekar:我已经添加了。非正式地,如果您通过 全局命名空间,那么您会直接到达 Base,而不是通过 Derived1
  • 我一直告诉人们可见性和可访问性是完全正交的。猜猜,由于另一个不起眼的角落案例,我不得不吃乌鸦……
  • 亲爱的@Bathsheba:非常感谢您的友好和详细的回复。很抱歉再次打扰您。如果::Base规避Derived1,为什么::Base::x不起作用?假设我们有一个Derived2对象d2,那么我们通过::Base访问的Based2中的基类子对象吗?
【解决方案2】:

改变这个:

Base::y;

到这个;

::Base::y;

【讨论】:

    最近更新 更多