如何从私有基类调用静态方法?
由于第三方库的布局,我有类似下面的代码:如何从私有基类调用静态方法?
struct Base
{
static void SomeStaticMethod(){}
};
struct Derived1: private Base {};
struct Derived2: public Derived1 {
void SomeInstanceMethod(){
Base::SomeStaticMethod();
}
};
int main() {
Derived2 d2;
d2.SomeInstanceMethod();
return 0;
}
我收到编译器错误C2247与MSVC:
基地:: SomeStaticMethod无法访问因为Derived1使用private来从Base继承。
我知道,从Derived2
通过继承我无法访问,因为私有符的Base
成员,但我仍然应该能够调用Base
一个静态方法 - 无论Base
和Derived2
之间的继承关系。
如何解决歧义并告诉编译器我只是在调用静态方法?
这样做:
struct Derived1: private Base {
protected:
using Base::SomeStaticMethod;
};
struct Derived2: public Derived1 {
void SomeInstanceMethod(){
Derived1::SomeStaticMethod();
}
};
否则,如果你想直接把它做提到@michalsrb:
struct Derived2: public Derived1 {
void SomeInstanceMethod(){
::Base::SomeStaticMethod();
// ^^
// Notice leading :: for accessing root namespace.
}
};
,如果你想叫它通过层次你可以这样做Base
。
几个可能的原因:
不要使用继承结构要调用的方法。使用
::Base::SomeStaticMethod()
来调用它。可以在全局名称空间中访问Base
。写
using Base::SomeStaticMethod;
我觉得michalsrb的答案是更能衬托private
功能进入Derived1
的命名空间,但是出于完整性:
namespace
{
void SomeStaticMethodProxy()
{
return Base::SomeStaticMethod();
}
}
struct Derived2: public Derived1 {
void SomeInstanceMethod(){
SomeStaticMethodProxy();
}
};
也会起作用。
其他答案提供了解决问题的方法,我会尝试解释发生了什么。这是因为注入了名字。
9.2(N4594)
[...]的类名也被插入到类本身的范围;这被称为注入类名称。 为了进行访问检查,注入类名称被视为是公共成员名称。 [...]即使你输入
Base::SomeStaticMethod()
注意,显然SomeStaticMethod
在Base
范围抬头(这是合格的名称),但名称Base
本身也有要查找莫名其妙,(在这个例子中为不合格的名称(因为它没有范围解析操作后出现))
会发生什么事是,当你在Derived2
搜索(unqalified)名称Base
,第一Derived2
范围进行搜索,然后Derived1
小号搜索cope,然后搜索Base
范围,最后找到注入类名称。然后访问控制发生(因为访问控制发生在名称查找后),它会发现你抬头的名字是Base
的成员,从Derived2
无法访问。
这不起作用(同样的错误C2247)。如果这是相关的,我正在使用MSVC 2013。 – Carlton
你确定吗?它*应该*工作?你写了领先的'::'吗? – Bathsheba
积极。我复制/粘贴你的代码并清理/重建我的项目。 – Carlton