c++ - Clang 编译有效,而 gcc 不适用于菱形继承(钻石问题)

标签 c++ inheritance gcc c++11 clang

我不确定我是否在这里遗漏了什么但似乎以下代码(在另一个我找不到的答案中可以找到类似的代码,顺便说一句,这里的问题是不同的)正在编译 just fine for clangnot compiling for gcc

#include <iostream>
using namespace std;

class base {
public:
 base(int i) {};

private:
 base(){};
};

class derivedA: virtual public base {
public:
 derivedA(int i) : base(i) {};

protected:
  derivedA() : base(0) {};
};

class derivedB: virtual public base {
public:
 derivedB(int i) : base(i) {};

protected:
  derivedB() : base(0) {};
};

class derivedAB : public derivedA, public derivedB {
public:
 derivedAB(int i) {};
 virtual ~derivedAB() = 0;
};

derivedAB::~derivedAB() {};

class lastDerived : public derivedAB {
public:
    lastDerived() : base(1), derivedAB(0) {};
};

int main(){
        lastDerived obj;
}

gcc 正在报告

main.cpp: In constructor 'derivedAB::derivedAB(int)':
main.cpp:9:2: error: 'base::base()' is private
  base(){};

哪一个是正确的行为?我会说 gcc 的一个,但我不确定为什么。

最佳答案

抽象类的虚拟基类不需要在该抽象基类的构造函数的mem-initializer-list中初始化。

这在 12.6.2p8 中讨论:

[...] and the entity is not a virtual base class of an abstract class [...]
[ Note: An abstract class (10.4) is never a most derived class, thus its constructors never initialize virtual base classes, therefore the corresponding mem-initializers may be omitted. — end note ]

所以clang是对的,gcc是不对的。如果 derivedAB 不是抽象的,这会有所不同。


DR 257 以来,这是 C++11 中的新津贴; g++ 对于 C++03 是正确的。 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19249 处存在 gcc 错误;也许它可以用戳戳来做。

关于c++ - Clang 编译有效,而 gcc 不适用于菱形继承(钻石问题),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24537075/

相关文章:

c++ - 如何在c++中检查对象类型

Java泛型结合接口(interface)继承

java - Java 中的不变性、协变性和逆变性

c++ - 如何使用 Armadillo 在不同的计算机上创建相同的随机数?

c++ - 使用 getline : C++ 读取文件并在屏幕上显示

gcc - 静态 C 变量未初始化

c - 学习 gcc 内部结构

xcode - Mac os x/usr/bin/gcc 文件

c++ - 尝试实现堆栈时 C++ 中的 undefined reference

c++ - OpenCV 中的 GStreamer 不通过 UDP 发送视频数据