我不确定我是否在这里遗漏了一些东西,但似乎以下代码(类似的代码可以找到我再也找不到的另一个答案,这里的问题不同)正在编译{ {3}}和just fine for clang
#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是一个,但我不确定为什么。
答案 0 :(得分:12)
抽象类的虚基类不需要在该抽象基类的构造函数的 mem-initializer-list 中初始化。
这将在12.6.2p8中讨论:
[...]并且实体不是抽象类的虚拟基类[...] [注意:抽象类(10.4)永远不是最派生的类,因此它的构造函数永远不会初始化虚拟基类,因此可以省略相应的mem-initializers。 - 结束记录]
所以clang是正确的,gcc是不正确的。这是不同的derivedAB
而不是抽象。
这是C ++ 11中的新容差,因为DR 257; g ++对于C ++ 03是正确的。在https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19249有一个gcc错误;也许它可以用戳戳。