我不知道我是否在这里遗漏了一些东西,但似乎下面的代码(类似的代码可以在另一个答案中找到,我再也找不到了,这里的问题与此不同)正在编译
just fine for clang和
not 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 […]
@H_404_24@
[ 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 ]所以叮当是正确的,gcc是不正确的.这不同于derivedAB而不是抽象.
自07年以来,这是C 11的新津贴; g对于C 03是正确的.在https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19249有一个gcc bug;也许它可以用戳.