我有两个这样的课程:
class Foo { public: Foo(int i) : _i(i) {} int _i; }; Q_DECLARE_METATYPE(Foo*)
class Bar : public Foo
{
public:
Bar(int i, int j) : Foo(i), _j(j) {}
int _j;
};
Q_DECLARE_METATYPE(Bar*)
我的板凳是这样的:
int main(int argc, char *argv[]) { QApplication a(argc, argv); Bar* bar = new Bar(10,11); QVariant var = QVariant::fromValue(bar); Foo * foo = var.value<Foo*>(); // foo IS NULL QPushButton * b = new QPushButton(); QVariant v = QVariant::fromValue(b); QObject * object = v.value<QObject*>(); // object IS NOT NULL return a.exec(); }
为什么foo
为空?
QVariant
允许多态,因为object
答案 0 :(得分:6)
因为Foo
不是从QObject
派生的,而QVariant
只支持QObject
派生类型的多态性。
来自QVariant::value documentation:
如果QVariant包含指向从QObject派生的类型的指针,则T可以是任何QObject类型。如果存储在QVariant中的指针可以是qobject_cast到T,则返回该结果。否则返回空指针。 请注意,这仅适用于使用Q_OBJECT宏的QObject子类。
(强调我的)。关于QVariant::canConvert
的部分进一步向下引用,并且没有关于指针转换的内容。 QVariant
根本不支持您的方案。
好处是,如果你将Foo
作为QObject
的子类,则不必再费心Q_DECLARE_METATYPE
了。
答案 1 :(得分:0)
问题是没有关于继承和没有虚拟表的元数据,因此QVariant
没有关于继承的数据。你可以尝试在基类中添加一些虚方法(析构函数最好),它可能会有所帮助(在这种情况下会有一些关于继承的运行时数据),但我认为这还不够。
与其他答案一样,此功能肯定适用于QObject
s。
您也可以尝试添加Q_GADGET
宏来提供元数据,但我怀疑它会解决问题。