在父类中暴露保护构造函数

问题描述 投票:3回答:1

就像标题所说的,我想知道是否有办法在派生类中公开一个保护的构造函数(也就是说,将访问权限从原来的 protectedpublic). 请考虑下面这个(人为的)例子。

struct A {
    int a;
    int b;
protected:
    A(int, int) {};
    void do_something();
};

struct B : A {
    B() : A(0, 0) {};
    using A::A;
    using A::do_something;
};

int main() {
    B b(0, 0); // error: 'A::A(int, int)' is protected
    //B b{}; // no errors
    b.do_something();
}

所以我们可以改变受保护成员函数的访问权限,但不能改变构造函数的访问权限?如果是这样,这个限制的理由是什么?


变通的方法。变量模板与参数转发可以作为一个变通的方法,它的性能是相同的。


理由推测:默认情况下,基类的构造函数不是常规意义上的 "继承",派生类的构造函数必须先构造基类实例。当 using 在常规成员函数上使用,它将函数引入到当前声明区域,从而改变了对构造函数的访问。using 只将基座构造函数带入 "正常继承 "级别(与其他成员函数相同,但不含 using). 因为只有在某些情况下,构造函数继承(重用基础构造函数)才有用,所以标准委员会的人指定为 using X::X 语法的构造函数继承,而不是更强的命名空间远传。

c++ inheritance language-lawyer encapsulation
1个回答
-2
投票

你要做的是调用构造函数B,有两个参数,但它不接受任何参数。

你得到的错误是关于B的构造函数是受保护的,但如果你仔细看,那不是你声明的构造函数。

error: 'B::B(int, int)' is protected

为什么会这样?因为编译器试图将你的调用解析为有效的东西,它发现基类的构造函数与签名相匹配。但它仍然是保护的,所以失败了。

你需要做的是,将受保护的构造函数 "重新启动 "到继承类中,就是提供一个匹配的构造函数。

struct B : A {
    B() : A(0, 0) {};
    B(int a, int b) : A(a, b) {};
    using A::A;
    using A::do_something;
};

int main() {
    B b;
    B b2(1, 2);
    //b.do_something();
}

http: /cpp. sh9tvik.

为什么不能像改变方法那样改变构造函数的访问器级别,原因很可能是要研究构造函数的非虚拟性。[引用:)]

© www.soinside.com 2019 - 2024. All rights reserved.