2010-11-21 80 views
10

在我的申请,我有下面的类层次结构:是否可以将模板派生的C++类与Qt的Q_OBJECT混合?

class Word 
{ 
    ... 
} 

template <typename T> class Dictionary 
{ 
    ... 
}; 

class WordDictionary : public Dictionary<Word> 
{ 
    Q_OBJECT 

    ... 
} 

的WordDictionary类解析字典这需要很长的时间。我正在一个单独的线程中运行解析函数,我希望它能够不时地发出GUI线程的信号,以便根据正在解析的当前行号提供进度更新。这就是为什么我希望它是一个Q_OBJECT。我试图让基类Dictionary为Q_OBJECT,但得到了一条消息,说明Q_OBJECT模板不受支持。当我删除了宏观,只留下WordDictionary为Q_OBJECT,我得到了一堆的一般形式的错误消息:

\ GeneratedFiles \发布\ moc_dictionary.cpp(44):错误C2039: 'staticMetaObject':是不是“词典”
与成员
[
T =字
]

有什么我可以做,使我的模板衍生WordDictionary类比硬编码模板功能以外的Q_OBJECT在这边,产生了很多样板代码?

编辑:更改模板声明:

template <typename T> class Dictionary : public QObject 

使代码编译。不过,我不确定我是不是在做一些愚蠢的事情,如果这能够正常工作的话。

+0

[为什么Qt没有为信号和插槽使用模板](http://qt-project.org/doc/qt-4.8/templates.html) – 2012-09-28 11:45:06

回答

14

你不能直接这样做,但有可用的工作轮。请参阅文章here

虽然在理论上是可能的 MOC处理模板,这将是 极其复杂的实现,并 将是非常不切实际的使用: 对于每个模板实例,MOC 必须产生适当的 元对象代码,并且将所生成的代码 将必须包含一次 每链接单元---成为一 恶梦保持一旦模板 类用于与不同的编译 同一模板 参数 单位。

如果信号和槽不需要 模板参数是 原型部分,解决办法是让 模板类继承 QObject的子类,它提供了所需的 信号和槽。如果 信号和插槽需要使用 模板参数,则可以使用Observer 模式。

2

我只是尝试这样的代码,它编译并运行正常:

#include <QtCore/QCoreApplication> 
#include <QObject> 

class Word 
{ 

}; 

template <typename T> class Dictionary 
{ 

}; 

class WordDictionary : public Dictionary<Word>, QObject 
{ 
    Q_OBJECT 
}; 

int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 
    WordDictionary wd(); 
    return a.exec(); 
} 

可能是我想的东西?

+0

这可能会产生问题,查看文章我引用了一个讨论。 – 2010-11-21 14:08:07

+0

@Steve:下线有什么问题?引用的文章只讨论试图从QObject派生类模板。这是从模板实例和QObject派生一个类。我看到的唯一问题是,QObject应该是继承列表中的第一个,因为moc假定第一个继承的类是QObject的子类。 – baysmith 2010-11-22 00:48:22

+3

QObject不应该成为第一个基类吗? – zarzych 2010-11-22 13:02:09