为什么继承的受保护构造函数不能公开?

Why can't an inherited protected constructor be made public?

本文关键字:不能 构造函数 继承 受保护 为什么      更新时间:2023-10-16

考虑:

class A
{
protected:
A(int) {}
void f(int) {}
public:
A() {}
};
class B : public A
{
public:
using A::A;
using A::f;
};
int main()
{
B().f(1); // ok
B(1); // error: 'A::A(int)' is protected within this context
}

为什么继承的protected构造函数不能public,而继承的protected成员函数可以?

与其他成员不同,引入继承构造函数的 using-声明的可访问性将被忽略。

[namespace.udecl]/19,

(强调我的(

由 using- 声明创建的同义词具有成员声明的通常可访问性。命名构造函数的using 声明器不会创建同义词;相反,如果其他构造函数在用于构造相应基类的对象时可访问,则其他构造函数是可访问的,并且USING-声明的可访问性将被忽略

实际上,继承的构造函数可以公开,但不仅仅是你编写它的方式。您可以按如下方式定义B类:

class B : public A {
public:
B() {}
B(int x) : A(x) {}  // instead of using A::A(int)
using A::f;
};

(见GodBolt(

也许标准委员会认为说using A::A会有点模棱两可,因为基类的构造函数与子类的构造函数并不完全相同。