在这种情况下,qobject_cast不应该默默地失败吗?

时间:2013-09-10 14:42:48

标签: c++ qt casting

我正在尝试在Qt中编写一个应用程序代码,直到我遇到这个愚蠢的问题。我有一个Node类,它可以有一个指向Workplace类实例的指针。我还为该指针定义了getter / setter方法。像这样:

class Node : public QGraphicsItem
{
    Q_DECLARE_TR_FUNCTIONS(Node)

public:
    Node(const QString &type, Project* nodeProject);
    ~Node();

    void setWorkplace(Workplace* workplace);
    void removeWorkplace();
    Workplace* usedWorkplace();

    (...)
private:    
    Workplace* myWorkplace;
}

所以,现在在我的代码中,我必须检查某个Node是否有指向Workplace的指针,以便对该信息进行一些操作。我就是这样做的:

Workplace* currentWorkplacePointer = qobject_cast<Workplace*>(node->usedWorkplace());
if(!currentWorkplacePointer){
     // no workplace, do some stuff
}else{
     // workplace exists, do other stuff
}

这完美无缺,但由于某种原因,它会随机随机。我随机说,因为有时,如果我尝试清理并重建项目,它可以正常工作 - 即qobject_cast无声地失败并按照我的意图进行处理;其他时候,即使我清理/重建,它也会再次发生故障。

调试器控制台始终指向上面代码中的对象强制转换线。据我所知,如果铸造的对象不存在,演员是否应该无声地失败?

请注意我对Qt / C ++很新,所以感谢任何帮助和评论 - 请保持温和! :)提前致谢!

2 个答案:

答案 0 :(得分:1)

塞巴斯蒂安·雷德尔(Sebastian Redl)也说,在自己的类型中投射指针似乎是无稽之谈。尽管如此,您的代码可以改进,以便将来使用。我的第一点来自qobject_cast的文档,该文档强制在您的类标题中调用Q_OBJECT宏以供使用。

其次,当您的Node继承QGraphicsItem时,我建议改用qgraphicsitem_cast,在处理或过滤场景中的项目时,会以不同的方式更快。适应doc

 class Node : public QGraphicsItem
 {
    ...
    enum { Type = UserType + 1 };

    int type() const
    {
        // Enable the use of qgraphicsitem_cast with this item.
        return Type;
    }
    ...
 }

//in your application code
Node *n = qgraphicsitem_cast<Node*>(expected_pointer_on_node);
if (n) {
//then n points a Node
}

答案 1 :(得分:0)

这实际上比我想象的要简单得多,我的问题实际上与node->usedWorkplace()方法无法返回任何内容有关,因为Workplace*在我试图去之前没有初始化得到它。愚蠢,我知道......

因此,我只是将指针初始化为0(谢谢你,@ chet f chet),并从那里开始工作。现在一切都很好。

因此,当我创建 Node的实例时,我将指针初始化为0

nodeToPlace->setWorkplace(0);

然后,当我想检查Workplace*实例是否存在Node时:

Workplace* tempWorkplace = node->usedWorkplace();
if(!tempWorkplace){
     // do stuff
}else{
     // other stuff
}

所以我根本不需要qobject_cast

注意:这最终没有关联/回答我关于qobject_cast默默失败的问题。我最终发现的是cast如果您尝试将0投射到某个内容中,则会在失败时返回0。我认为,我的初始代码后者正在发生。

IBM Linux Compilers documentation(根据Qt的文档大致相同的报告到C ++的dynamic_cast):

  

表达式dynamic_cast(v)将表达式v转换为类型T.   类型T必须是指向完整类类型或a的指针或引用   指向void的指针。如果T是指针和dynamic_cast运算符   如果失败,则运算符返回类型为T的空指针。如果T为a   引用和dynamic_cast运算符失败,运算符抛出   exception std :: bad_cast。

因此,我会得出结论,我正在引用垃圾作为演员的arg,这使得我的应用程序出错(正如@hyde在评论中提到的那样,因此我也给他+1了)。

如果有人有不同的意见和/或解释,请告诉我 - 我想了解更多有关我的错误/错误的信息。