我正在尝试测试我班级的受保护方法和构造函数。为此,我尝试将其子类化,并使用C ++ 11 using
关键字将其成员重新导出为公共:
class Foo {
protected:
Foo(int i) {}
void run() {}
};
class TestableFoo : public Foo {
public:
using Foo::Foo;
using Foo::run;
};
int main() {
TestableFoo foo(7);
foo.run();
}
但是,g ++和clang ++都无法编译它,产生以下错误:
test.cpp:13:15: error: ‘TestableFoo::TestableFoo(int)’ is protected
using Foo::Foo;
^
test.cpp:18:16: error: within this context
TestableFoo foo(7);
^
即使run
方法公开(我单独确认),TestableFoo构造函数仍然受到保护。为什么会这样?我可以理解决策(继承与覆盖可见性),但为什么方法和构造函数之间存在不一致?
答案 0 :(得分:4)
标准明确声明继承的构造函数保留其访问级别:
12.9继承构造函数[class.inhctor]
1使用声明(7.3.3)隐式命名构造函数 声明一组继承构造函数。候选人集 继承了using-declaration中命名的类
X
的构造函数 由实际的构造函数和由此产生的名义构造函数组成 从默认参数的转换如下:
[案例清单]
4 如此声明的构造函数具有与对应的相同的访问权限 X中的构造函数。如果
X
中的相应构造函数,它将被删除 被删除(8.4)。
您当然可以直接调用它:
TestableFoo(int i) : Foo(i) { }
答案 1 :(得分:1)
此行为符合标准所述(ISO / IEC 14822:2011 12.9,§4):
如此声明的构造函数具有与X中相应构造函数相同的访问权限。
其中X
是继承构造函数的基类。
要获得所需的行为,您可以使用:
class TestableFoo : public Foo {
public :
TestableFoo(int i) : Foo(i) { }
using Foo::run;
};