C++11 inheriting constructors and access modifiers
假设如下布局:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Base
{
protected:
Base(P1 p1, P2 p2, P3 p3);
public:
virtual void SomeMethod() = 0;
}
class Derived : public Base
{
public:
using Base::Base;
public:
virtual void SomeMethod() override;
}; |
我可以在这里指定Derived的构造函数为公共的吗?VC++给出以下错误:
cannot access protected member declared in class 'Derived'
compiler has generated 'Derived::Derived' here [points to the using Base::Base
line]
see declaration of 'Derived'
号
也就是说,它忽略了继承构造函数上方的访问修饰符。
这是功能的限制吗?Base类有一个公共构造函数是没有意义的,因为它永远不能直接实例化(由于是纯虚拟方法)。
根据12.9/4,"继承建设者",在说using X::X时,
A constructor so declared has the same access as the corresponding constructor in X.
号
所以继承的构造函数也是protected。
- GCC 4.8的例子。
- 等等,构造器有什么特别的?同样的事情不适用于常规函数…
- @圣殿骑士团:我知道,我在问为什么。
- @mehrdad[namespace.udecl]/18具有:"由using声明创建的别名通常具有成员声明的可访问性。[注意:命名构造函数的using声明不会创建别名;有关可访问性规则,请参阅12.9。-尾注]"
- @圣殿骑士团:很好的引用!我想知道为什么构造函数的特殊情况,比如我们还没有足够的不一致性……
- @马蒂厄姆。我不知道,它从一开始就在草稿纸上,没有任何解释。而且,确实有点讽刺的是,一个旨在使构造函数更为规则的w.r.t.普通函数的建议,仍然会留下这种小的不一致性。
- @Matthieum.:这是一个很好的问题,为什么构造函数不同于成员函数,但是考虑到它们(在许多意义上),我相信这条规则有一个很好的理由。不过,我得考虑一下。也许在最初的提议中有线索?
- @Matthieum.:因此,本次讨论的唯一提及的是N1583,它是N2203和N254修订版之间的引用源,在这里进行了更改。但这不是一个真正的论点,只是一个需要澄清的注释。
- @Kerreksb:有趣的是,这意味着using Base::Base不同于转发构造函数…
- @matthieum.:是的-using声明使所有符合条件的基本构造函数都可见,而不仅仅是一个。
- @Kerreksb:好吧,这与基类中的重载方法是内联的;我只是在提到这个奇怪的可访问性问题,因为转发构造函数重新定义了可访问性,而using Base::Base没有:/
- 在C++ 14中这仍然是真的吗?
- @约瑟夫加文:我想是的,即使在世界语中,措辞也是一样的。
- 是否有人提交了缺陷/RFC/这方面的内容?似乎是错的。