我有一个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*
。
答案 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不同。我不知道对象实际上已经死了,我的动作中的所有字符串和变量都是有效的。