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

Posted

技术标签:

【中文标题】为啥不能将继承的受保护构造函数公开?【英文标题】:Why can't an inherited protected constructor be made public?为什么不能将继承的受保护构造函数公开? 【发布时间】:2020-09-17 19:05:02 【问题描述】:

考虑:

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成员函数可以?

【问题讨论】:

【参考方案1】:

实际上,继承的构造函数可以公开,但不仅仅是您编写的方式。您可以按如下方式定义您的 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 会有点模棱两可,因为基类的构造函数与子类的构造函数并不完全相同。

【讨论】:

【参考方案2】:

与其他成员不同,引入 inherited constructor 的 using 声明的可访问性被忽略。

[namespace.udecl]/19,

(强调我的)

using-declaration 创建的同义词具有member-declaration 的通常可访问性。命名构造函数的using-declarator 不会创建同义词;相反,如果附加的构造函数在用于构造相应基类的对象时可访问,那么它们是可访问的,并且 using-declaration 的可访问性被忽略。

【讨论】:

以上是关于为啥不能将继承的受保护构造函数公开?的主要内容,如果未能解决你的问题,请参考以下文章

C++:为啥我的 DerivedClass 的构造函数无法访问 BaseClass 的受保护字段?

为啥抽象类的构造函数应该受到保护,而不是公开的?

创建类的受保护构造函数有啥好处和坏处

具体类中的受保护构造函数与抽象类中的公共构造函数

抽象类的受保护与公共构造函数?有区别吗?

在 C# 中调用类的受保护构造函数