2015-04-23 160 views
0

我有没有虚函数的类,这个类包含另一个类,这里​​是他们的定义:奇怪的链接错误未定义引用的vtable

class StorageManager : public QObject { 
    Q_OBJECT 
protected: 

    class AbstractWrapper { 
    public: 
     virtual void action1() = 0; 
     virtual void action2() = 0; 
     virtual void action3() = 0; 
     virtual ~AbstractWrapper() {} 
    }; 

    class AbstractStorage { 
    public: 
     virtual QSharedPointer<AbstractWrapper> getWrapper(QString key) = 0; 
     virtual QSharedPointer<AbstractWrapper> newWrapper(QString key) = 0; 
     virtual void deleteWrapper(QString key) = 0; 
     virtual ~AbstractStorage() {} 
    }; 

    template<typename T> 
    class Wrapper { 
    public: 
     virtual void action1() { /* do stuff */ } 
     virtual void action2() { /* do stuff */ } 
     virtual void action3() { /* do stuff */ } 
     virtual ~Wrapper() {} 
    private: 
     T * realContent; 
    }; 

    template<typename T> 
    class Storage { 
    public: 
     virtual QSharedPointer<AbstractWrapper> getWrapper(QString key) 
     { 
      return new Wrapper<T>(storage.value(key)); 
     } 
     virtual QSharedPointer<AbstractWrapper> newWrapper(QString key) 
     { 
      T * tmp = new T(); 

      QObject::connect(tmp,   SIGNAL(signal(int)), 
          &dispatcher, SLOT(slot(int))); 
      storage.insert(key, tmp); 
      return new Wrapper<T>(tmp); 
     } 

     virtual void deleteWrapper(QString key) 
     { 
      T * tmp = storage.value(key); 
      disconnect(tmp, SIGNAL(signal(int)), 
         &dispatcher, SLOT(slot(int))); 
      delete tmp; 
      storage.remove(key); 
     } 

     virtual ~Storage() {} 
    private: 
     QHash<QString, T *> storage; 
    }; 

private: 

    static Storage<ClassA> classAStorage; 
    static Storage<ClassB> classBStorage; 
    static Storage<ClassC> classCStorage; 

    static StorageManager dispatcher; 

public: 
    static AbstractStorage * getStorage(int classid) 
    { 
      if(classid == 'A') return &classAStorage; 
     else if(classid == 'B') return &classBStorage; 
     else if(classid == 'C') return &classCStorage; 
     else throw std::exception(); 
    } 

    public void connectDispatcher(QObject * receiver, const char * method) 
    { 
     connect(&dispatcher, SIGNAL(dispatch_signal(int)), receiver, method); 
    } 

public slots: 
    void slot(int output) 
    { 
     emit dispatch_signal(output); 
    } 

signals: 
    void dispatch_signal(int); 

} 

我也有所有的静态initiliazations .cpp文件。

编译时,我没有编译错误。但是,一个链接错误:

undefined reference to `vtable for StorageManager' 

此错误标记的类定义行:

class StorageManager : public QObject { 

我知道这种错误是与纯虚不超载,但我没有看到这个错误在我的代码...

感谢您的帮助


编辑:

答案:该文件不是由moc编译的。 解决方案:从项目中删除文件,使用“添加新...”,“C++类”添加相同的类。三重检查你是否选择QObject作为父类。

这可能是一个QtCreator相关的bug,这appens与QtCreator 3.3.2从版本3af3fe7ad3

+0

您是否在构建项目之前运行qmake? – vahancho

+0

是的,我使用QtCreator(其他Q_OBJECT类没有问题)。在发布这个问题之前,我做了完整的重建;) – AMDG

+0

头文件是否在'.pro'文件中的'HEADERS'中列出? – Wintermute

回答

0

发现的解决方案!

头文件没有被moc编译器编译,而是在.pro文件中。

要解决该问题:从项目中删除标题和源文件。清理你的项目。建立你的项目。

然后用QtCreator助手添加类:

  • 新增...
  • C++类
  • 名称类,选择的QObject作为基类

然后重新生成项目,那应该没问题。


这可能是一个QtCreator相关的bug,这与QtCreator 3.3.2 appens从版本3af3fe7ad3。