使用`using`关键字将继承的构造函数设为公共访问权限

10

我正在尝试测试我的类的受保护方法和构造函数。为此,我尝试使用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 构造函数仍然是受保护的(我已经单独确认过)。为什么会这样?我可以理解继承和覆盖可见性的任何一种决策,但为什么方法和构造函数之间存在不一致性?


相关内容- https://dev59.com/I4Dba4cB1Zd3GeqPCEii - 但没有回答为什么 - Praetorian
2
“为什么”可能是因为否则它会改变所有构造函数的可访问性,这可能被认为比不能在这种情况下继承它们的不便更糟糕。但这只是一个猜测。 - Mike Seymour
2个回答

5
标准明确指出,继承的构造函数保留其访问级别:
12.9 继承构造函数 [class.inhctor]
1 使用声明(7.3.3)命名构造函数隐含地声明了一组继承构造函数。使用声明中命名的类X的候选继承构造函数集包括实际构造函数和由默认参数转换而来的概念构造函数,具体如下:
[省略案例列表]
4 声明为这样的构造函数具有与X中相应构造函数相同的访问权限。如果X中的相应构造函数被删除,则该构造函数也被删除(8.4)。
当然,您可以直接调用它:
TestableFoo(int i) : Foo(i) { }

1
这种行为符合标准规定(ISO/IEC 14822:2011 12.9, §4):

声明为此类型的构造函数与 X 类中相应构造函数具有相同的访问权限。

其中 X 是从中继承构造函数的基类。

要获得所需的行为,可以使用:

class TestableFoo : public Foo {
  public :
    TestableFoo(int i) : Foo(i) { }
    using Foo::run;
};

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