当Object有效且活着时,d_ptr是否可能为NULL?

时间:2014-04-16 09:07:42

标签: c++ qt

我有一个MyAction类,它源自QWidgetAction派生自QAction的{​​{1}}。 当我致电QWidget::addActions(QList<QAction*> actions)时,我尝试获取d_ptr并在列表中的操作中使用它(在QWidget内,而非我自己),我有例外:

QActionPrivate *apriv = action->d_func();
apriv->widgets.append(this);

以上代码取自QWidget源文件。顺便说一句,我的动作被放置在动作列表中,作为this指针的类型,其类型为MyAction:

actions->push_back(this);

我认为异常的原因在于我试图将QList推入我的类MyAction,将const this指针转换为QAction*

3 个答案:

答案 0 :(得分:0)

如果正确使用d-pointer模式,那么它永远不能为空。 D指针必须指向有效的内存块,只要对象存在,它就会存活。

此角色唯一的例外是在写入时实现copy的类,它提供null状态(例如QString),但这绝不适用于QObjects

您的问题必须是悬挂指针或其他内存问题的结果。或者错误的类型转换。在这种情况下,调用堆栈不必指向问题的根源,问题几乎可以在任何地方。

我建议使用valgrind或其他内存检查工具运行程序。或者一些静态分析工具。

答案 1 :(得分:0)

您永远不应该使用客户端代码中的d_func()pimpl idiom的重点是远离实现细节,库可以自由地更改实现细节,如数据表示,内部方法等。

也就是说,d_func()和d_ptr用于内部使用。如果由于某种原因需要访问它,这意味着您似乎违反了库的设计原则,或者您尝试访问应该暴露给API的内容,但是还不需要。

根据您确切的用例 - 我们不知道,我建议考虑这些替代方案。

答案 2 :(得分:0)

问题在于我在堆栈上创建了MyAction变量,所以,实际上,当我试图将它传递给QWidget函数时,QObject还没有存活。这就是为什么我不能让d指针与NULL不同。我不知道对象实际上已经死了,我的动作中的所有字符串和变量都是有效的。