在C++中,派生类中的静态方法能否调用受保护的构造函数?

21

这段代码在clang上可以工作,但g++报错:

错误:‘A::A()’是受保护的

class A
{
protected:
    A() {}
};

class B : public A
{
    static A f() { return A(); } // GCC claims this is an error
};

哪个编译器是正确的?

1个回答

11

g++是正确的。

C++标准中的第11.5/1节规定:“<...>访问必须通过指向、引用或对象本身的指针<...>”。对于构造函数来说,这意味着B只能调用A的受保护构造函数来构造自己的基类子对象。

请查看在g++中与此相关的问题这里。该问题被关闭,因为它不是一个错误。


2
关于理由,protected 提供了对 B 内部的 A 子对象的访问权限,而不是任何 A。另一个例子是 struct C : A { static void break_invariants( B& b ) { b.protected_member_from_A = 5; } };,这可能会破坏 B 中保持的不变量。 - David Rodríguez - dribeas
David:有趣的是你这么说,因为GCC确实允许从派生类的静态方法中访问(修改)基类的受保护静态数据成员。那么你认为这是GCC的一个bug吗? - John Zwinck
@Kirill:这个标准的那一部分只适用于构造函数吗?因为在GCC下,普通命名方法和数据成员似乎可以以类似的方式访问。 - John Zwinck
1
@John Zwinck,不,这不仅仅是关于构造函数的问题。可能你使用了静态成员或者通过this(隐式地)使用了普通命名方法。 - Kirill V. Lyadvinsky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接