【发布时间】:2014-04-22 20:08:53
【问题描述】:
我在静态库中有以下构造(调度机制的一部分,为简洁起见删除了不相关的细节):
class Base {
protected:
Base(Connection* conn = nullptr) : myConn(conn) {;} // = nullptr fixes the problem
Connection* myConn;
};
class Handler : virtual public Base {
public:
virtual void handleMessage(InputStream&) = 0;
protected:
Handler(int id) : myId(id) {;} <<<<< Error <<<<<<<
const int myId;
};
template<class EventType>
class TypedHandler : public Handler
{
protected:
TypedHandler() : Handler(EventType::ID) {;}
virtual void onEvent(const EventType&) = 0;
private:
virtual void handleMessage(InputStream& message)
{
EventType event(message);
onEvent( event );
}
};
我完全知道最派生的类应该初始化基类,它看起来像:
class A : public TypedHandler<SuperEvent>
, public TypedHandler<DuperEvent>
{
public:
A(Connection* conn) : Base(conn) {}
void onEvent(const SuperEvent&)
{ ... }
void onEvent(const DuperEvent&)
{ ... }
};
但是我在标记的位置(VS 2012,MSVC++ 11)得到“错误 C2512:没有适当的默认构造函数可用的虚拟基类”,即使 Handler 从来都不是最衍生的......
想法?
编辑:通过允许生成默认构造函数(通过构造函数中的Connection* conn = nullptr),它可以工作。根据 Igor 的链接,不会在 Handler 构造函数中调用默认构造函数,因为 Handler 是虚拟的。
Edit2:通过将虚拟基类的默认构造函数设置为private,并将直接的两个子类设置为friends+非默认构造函数为protected,不仅可以编译,而且如果最派生类没有初始化正确的虚拟基类。所有复选框都打勾! :)
【问题讨论】:
-
谢谢@Igor,真令人失望。但是 GCC 的 bug 真的很老了,这方面没有任何进展吗?
标签: c++ visual-c++ virtual