在我的应用程序中,我有以下类层次结构:
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 \ Release \ moc_dictionary.cpp(44):错误C2039:'staticMetaObject':不是'Dictionary'的成员
与
[
T =字
]
我能做些什么来使我的模板派生的WordDictionary类成为Q_OBJECT,而不是硬编码里面的模板函数,产生大量的样板代码?
编辑:将模板声明更改为:
template <typename T> class Dictionary : public QObject
使代码编译。我不确定我是不是做了一些愚蠢的事情,如果这样做会正常的话。
答案 0 :(得分:14)
你不能直接这样做,但有可用的工作轮。请参阅文章here。
虽然理论上可行 moc来处理模板,它会 实施极其复杂,并且 使用是非常不切实际的: 对于每个模板实例化,moc 必须生成适当的 元对象代码,以及生成的 代码必须包含一次 每个链接单位---成为一个 噩梦维持一次模板 class与同一模板一起使用 不同编译中的参数 单元。
如果信号和插槽不需要 模板参数是其中的一部分 原型,解决方法是 使模板类继承一个 提供的QObject子类 所需信号和插槽。如果 信号和插槽需要使用 模板参数,Observer 模式是另一种选择。
答案 1 :(得分: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();
}
可能是我错过了什么?