5

我有两个这样的课程:

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();
}

为什么是foonull ? QVariant让多态性因为我没有问题object

4

2 回答 2

7

因为Foo不是派生自QObjectQVariant仅支持QObject派生类型的多态性。

来自QVariant::value 文档

如果 QVariant 包含指向从 QObject 派生的类型的指针,则 T 可以是任何 QObject 类型。如果存储在 QVariant 中的指针可以 qobject_cast 到 T,则返回该结果。否则返回空指针。请注意,这只适用于使用 Q_OBJECT 宏的 QObject 子类。

(强调我的)。这在进一步引用的部分中重新散列QVariant::canConvert,并且没有关于指针转换的其他内容。QVariant根本不支持您的方案。

好处是,如果你创建Foo一个 的子类QObject,你就不必再费心Q_DECLARE_METATYPE了。

于 2015-01-09T09:45:30.173 回答
0

问题是没有关于继承的元数据,也没有虚拟表,所以QVariant没有关于继承的数据。您可以尝试向基类添加一些虚拟方法(最好使用析构函数),它可能会有所帮助(在这种情况下会有一些关于继承的运行时数据)但我认为这还不够。
与其他答案一样,此功能肯定适用于QObjects。

您也可以尝试添加Q_GADGET宏来提供元数据,但我怀疑它会解决问题。

于 2015-01-09T12:57:30.607 回答