派生类中继承的(->“使用”)基类 ctor / 运算符的访问说明符是什么?

What are the access specifiers of inherited (-> "using") base class ctors / operators in derived class?

提问人:glades 提问时间:1/20/2023 最后编辑:Vlad from Moscowglades 更新时间:1/21/2023 访问量:110

问:

在下面的代码中,您可以看到我正在将基类 ctor 继承到“private”访问说明符下的派生类中。我最初的想法是,这些将适应我给出的访问说明符(这里是“私有”),因此无法使用,但我似乎错了。继承基类构造函数和有关派生类中访问说明符的运算符的规则是什么?

演示

#include <cstdio>

class base
{
public:
    base(int i) {
        printf("Public base class ctor called!");
    }
private:
    base(bool b) {
        printf("Private base class ctor called!");
    }
};


class derived final : public base
{
private:
    using base::base;
};

int main()
{
    derived d(2);

    // issues "is private within this context"
    // derived e(true);
}

输出:

Public base class ctor called!

(在这种情况下,预期派生的 CTOR 是“私有的”)

C++ 访问说明符 using-declaration 继承构造函数

评论

0赞 Jarod42 1/20/2023
来自 doc:“在初始化派生类时,该基的所有构造函数(忽略成员访问)都可见,以重载解析。
0赞 glades 1/20/2023
@Jarod42 这听起来不对,因为在派生类中也无法访问私有 ctor。见更新后的问题中的dervied e。
0赞 Nicol Bolas 1/21/2023
@glades:中引入的私有构造函数不会被继承。因此,该条款不适用。derived
0赞 sklott 1/21/2023
可见到重载分辨率并不意味着它可以访问,但它将参与重载解决。假设您有构造函数和构造函数。没有表达式会成功编译,但有表达式不会。base(char v)derived(int v)using base::base;derived d('c');using

答:

4赞 Vlad from Moscow 1/20/2023 #1

摘自 C++ 17 标准(10.3.3 使用声明)

19 由 using 声明创建的同义词具有通常的 成员声明的可访问性。一个使用声明符,它命名 构造函数不创建同义词;取而代之的是,附加的 如果构造函数在用于 构造一个对应基类的对象,并且 using-declaration 的可访问性将被忽略。

因此,正如在您的示例中一样,第一个构造函数(带有类型的参数)可以在基类中访问,然后派生类中相应的继承构造函数也可以访问。int

另一方面,第二个构造函数(带有类型的参数)是私有的。因此,对于派生类的第二个对象定义bool

derived e(true);

编译器将发出错误。

事实上,继承的构造函数也继承访问控制。

评论

0赞 Peter 1/21/2023
derived e(true)将导致在无法访问该构造函数的任何上下文中进行诊断。构造函数被标识为要调用的候选对象,而不管其可访问性如何。然后检查其访问权限,并且 - 对于非非成员,将出现可诊断的错误。derived(bool)friendderived