这个问题在这里已有答案:
class A {
protected:
A(int) {}
};
struct B : public A {
public:
using A::A;
};
void print(B b) {}
int main(int argc, char** argv) {
print(1);
return 0;
}
这段代码不能编译......即使在struct B public section中使用'using A :: A',B仍然没有公共构造函数接受int(但它有一个受保护的)。
看起来 :
我可以使用'using'继承公共构造函数
我可以在派生类中重新声明为基类中定义的任何方法(私有或受保护或其他)
但我不能对构造函数做同样的事情:无法用'使用'来改变它的可见性
为什么?
这是故意的。请注意,A::A
继承了每个构造函数,而不仅仅是您期望的构造函数。将using
的访问修饰符应用于每个继承的构造函数可能会影响太大。相反,它只是使它们可用于重载解析。
来自cppreference:
如果using声明引用了正在定义的类的直接基础的构造函数(例如
using Base::Base;
),那么在初始化派生类时,该基础的所有构造函数(忽略成员访问)都会变得可见以重载解析。如果重载决策选择了继承的构造函数,则在用于构造相应基类的对象时可以访问它是可访问的:引入它的using-declaration的可访问性将被忽略。
如果你想在构造A::A(int)
时调用B
,你可以自己实现B::B(int)
,以便它调用它。
来自cppreference:
如果重载决策选择了继承的构造函数,则在用于构造相应基类的对象时可以访问它是可访问的:引入它的using-declaration的可访问性将被忽略。
一个可能的基本原理是构造函数通常具有不同的可访问性,这可能是至关重要的,而使用声明无法区分它们,并且如果使用了使用点的可访问性,它们将赋予它们相同的可访问性。
如果using
声明的当前访问说明符更改了“继承”构造函数的访问说明符,那么单独的“继承”构造函数将无法使用不同的访问说明符。
如果基类确实具有多个具有不同访问权限的构造函数,那么通常希望可访问性保留在派生类中。 using
的规则使这成为可能。