模板化 Q_OBJECT 基础 class
Templated Q_OBJECT base class
我有几个 classes:
A.h
class Abase_obj : public QObject
{
Q_OBJECT
Q_PROPERTY(QAction* playAction READ playAction CONSTANT)
public:
Abase_obj(QObject* parent = nullptr) : QObject(parent) {}
virtual QAction* playAction() = 0;
signals:
void someSignal()
slots:
virtual void baseSlot() = 0;
};
template <class T>
class Abase : public Abase_obj
{
public:
Abase(QObject* parent = nullptr) : Abase_obj(parent) {...}
void baseSlot() override;
QAction* playAction() override;
protected:
QWeakPointer<T> m_currentItem;
};
template <class T>
Abase<T>::baseSlot() {
auto item = m_currentItem.lock();
item->someMethodOfTemplateClass(); // here is the error
}
B_inh.h
#include "A.h"
class MediaItem;
class B_inh : public Abase<MediaItem>
{
Q_OBJECT
Q_PROPERTY(MediaItem* getItem READ getItem)
public:
// constructor
MediaItem* getItem();
public slot:
// some new slot
}
所以我使用 Abase_obj 因为我不能在模板 class 中键入 Q_OBJECT 宏并在那里定义一些槽和信号。我知道我可以定义没有模板化 parametres 的插槽。但是我是直接在这个插槽中使用模板方法。但是由于 Abase_obj 元对象不知道这个 class,我得到错误:error: C2039: 'someMethodOfTemplateClass': is not member of 'QSharedPointer' 和 错误:C2027:使用未定义的类型 'MediaItem'。所以我有两个问题:第一个是我应该如何实现这个插槽才能工作,第二个问题在上面的评论中。
Upd:如果我 #include "MediaItem.h" 而不是转发声明它,我会收到错误消息:
LNK2001: unresolved external symbol "public: static struct QMetaObject const Abase_obj::staticMetaObject" : in file B_inh.cpp.obj
LNK2001: unresolved external symbol "public: virtual void * __cdecl Abase_obj::qt_metacast(char const *)" : in file B_inh.cpp.obj
LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __cdecl Abase_obj::metaObject(void)const " : in file B_inh.cpp.obj
如果我从 Abase_obj 中删除 Q_OBJECT 宏和所有 Q_PROPERTies 并将它们添加到 B_inh class,一切都在编译和工作,但是我不想每次都在所有派生的 classes
中实现这些属性
代码正确。错误出在我的 qbs dependencies 中。文件 A.h 还没有被编译,也没有被正确地包含到 B_inh.h,所以我遇到了这些链接器错误
我有几个 classes:
A.h
class Abase_obj : public QObject
{
Q_OBJECT
Q_PROPERTY(QAction* playAction READ playAction CONSTANT)
public:
Abase_obj(QObject* parent = nullptr) : QObject(parent) {}
virtual QAction* playAction() = 0;
signals:
void someSignal()
slots:
virtual void baseSlot() = 0;
};
template <class T>
class Abase : public Abase_obj
{
public:
Abase(QObject* parent = nullptr) : Abase_obj(parent) {...}
void baseSlot() override;
QAction* playAction() override;
protected:
QWeakPointer<T> m_currentItem;
};
template <class T>
Abase<T>::baseSlot() {
auto item = m_currentItem.lock();
item->someMethodOfTemplateClass(); // here is the error
}
B_inh.h
#include "A.h"
class MediaItem;
class B_inh : public Abase<MediaItem>
{
Q_OBJECT
Q_PROPERTY(MediaItem* getItem READ getItem)
public:
// constructor
MediaItem* getItem();
public slot:
// some new slot
}
所以我使用 Abase_obj 因为我不能在模板 class 中键入 Q_OBJECT 宏并在那里定义一些槽和信号。我知道我可以定义没有模板化 parametres 的插槽。但是我是直接在这个插槽中使用模板方法。但是由于 Abase_obj 元对象不知道这个 class,我得到错误:error: C2039: 'someMethodOfTemplateClass': is not member of 'QSharedPointer' 和 错误:C2027:使用未定义的类型 'MediaItem'。所以我有两个问题:第一个是我应该如何实现这个插槽才能工作,第二个问题在上面的评论中。
Upd:如果我 #include "MediaItem.h" 而不是转发声明它,我会收到错误消息:
LNK2001: unresolved external symbol "public: static struct QMetaObject const Abase_obj::staticMetaObject" : in file B_inh.cpp.obj
LNK2001: unresolved external symbol "public: virtual void * __cdecl Abase_obj::qt_metacast(char const *)" : in file B_inh.cpp.obj
LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __cdecl Abase_obj::metaObject(void)const " : in file B_inh.cpp.obj
如果我从 Abase_obj 中删除 Q_OBJECT 宏和所有 Q_PROPERTies 并将它们添加到 B_inh class,一切都在编译和工作,但是我不想每次都在所有派生的 classes
中实现这些属性代码正确。错误出在我的 qbs dependencies 中。文件 A.h 还没有被编译,也没有被正确地包含到 B_inh.h,所以我遇到了这些链接器错误