访问以私有方式指定的基类的公共静态成员。

11
我正在学习C ++。文档learn.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;
}

2
使用 ::Base::y 来正确获取作用域。 - Peter
1
我认为微软的示例有问题。 - molbdnilo
2个回答

16

这份文档有点误导人。

正确的编译器行为是,如果您使用该符号尝试访问静态成员,则 Base::yBase :: x 都应该在 Derived 中无法访问。

但是,你可以通过在另一个作用域解析运算符下使用全局命名空间(从而规避 Derived1),来访问它:

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

最后,不要忘记定义y的位置,如果你希望链接阶段能够成功。


4
有时候,名称查找规则的路径查找令人非常沮丧。 - StoryTeller - Unslander Monica
1
@Bathsheba,您能否在上面的示例中添加另一个作用域解析符的说明呢?这对我非常有帮助。谢谢! - Pravar Jawalekar
1
@PravarJawalekar:我已经添加了那个。非正式地说,如果您通过全局命名空间,则可以直接到达Base,而无需通过Derived1 - Bathsheba
我一直告诉别人,可见性和可访问性是完全不相关的。猜猜,我现在得承认我错了,这要归因于另一个晦涩的特例…… - Arne Vogel
亲爱的@Bathsheba:非常感谢您的友善和详细回复。再次打扰您很抱歉。如果::Base绕过了Derived1,为什么::Base::x不起作用?假设我们有一个Derived2对象d2,我们通过::Base访问的Based2中的基类子对象吗? - KarlEL
@KarlEL 你需要一个 Base实例来访问 x,因为后者是一个非static成员。 - Bathsheba

2

将其改为:

Base::y;

转换为这个:

::Base::y;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接