使用'using'关键字使继承的构造函数public

时间:2014-07-08 15:33:46

标签: c++ inheritance testing c++11 using

我正在尝试测试我班级的受保护方法和构造函数。为此,我尝试将其子类化,并使用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构造函数仍然受到保护。为什么会这样?我可以理解决策(继承与覆盖可见性),但为什么方法和构造函数之间存在不一致?

2 个答案:

答案 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;
};