using语句和受保护的构造函数[duplicate]

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

这个问题在这里已有答案:

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'继承公共构造函数

我可以在派生类中重新声明为基类中定义的任何方法(私有或受保护或其他)

但我不能对构造函数做同样的事情:无法用'使用'来改变它的可见性

为什么?

c++
3个回答
4
投票

这是故意的。请注意,A::A继承了每个构造函数,而不仅仅是您期望的构造函数。将using的访问修饰符应用于每个继承的构造函数可能会影响太大。相反,它只是使它们可用于重载解析。

来自cppreference

如果using声明引用了正在定义的类的直接基础的构造函数(例如using Base::Base;),那么在初始化派生类时,该基础的所有构造函数(忽略成员访问)都会变得可见以重载解析。

如果重载决策选择了继承的构造函数,则在用于构造相应基类的对象时可以访问它是可访问的:引入它的using-declaration的可访问性将被忽略。

如果你想在构造A::A(int)时调用B,你可以自己实现B::B(int),以便它调用它。


4
投票

来自cppreference

如果重载决策选择了继承的构造函数,则在用于构造相应基类的对象时可以访问它是可访问的:引入它的using-declaration的可访问性将被忽略。

一个可能的基本原理是构造函数通常具有不同的可访问性,这可能是至关重要的,而使用声明无法区分它们,并且如果使用了使用点的可访问性,它们将赋予它们相同的可访问性。


1
投票

如果using声明的当前访问说明符更改了“继承”构造函数的访问说明符,那么单独的“继承”构造函数将无法使用不同的访问说明符。

如果基类确实具有多个具有不同访问权限的构造函数,那么通常希望可访问性保留在派生类中。 using的规则使这成为可能。


推荐问答