智能指针作为 QObject::deleteLater() 的替代品
Posted
技术标签:
【中文标题】智能指针作为 QObject::deleteLater() 的替代品【英文标题】:Smart pointers as an alternative to QObject::deleteLater() 【发布时间】:2019-01-20 19:13:42 【问题描述】:所以我有一个发出网络请求的函数:
void MyClass::makeRequest()
ApiRequest* apiRequest = new ApiRequest();
apiRequest->makeRequest();
connect(apiRequest, &ApiRequest::requestFinished, this, &MyClass:onApiRequestFinished);
由于我需要对象 apiRequest
生存直到我的请求完成,所以我调用:
void MyClass:onApiRequestFinished()
// do my stuff
// now I can delete my request object ((retrieved using sender()) using deleteLater()
既然在这种情况下我没有使用 Qt 父子系统,我该如何使用 C++11 智能指针而不是调用 deleteLater()
来管理内存?
【问题讨论】:
根据我的经验,最好不要尝试将 Qt 的父子系统与智能指针混合;也就是说,如果您使用 Qt 的系统来处理 QObject 派生的对象和仅用于非 QObject 派生的对象的智能指针,那么您的生活将不会那么痛苦。 除了 Jeremy:如果智能指针指向它,您不应该明确删除(通过delete
或类似的东西)。通常,智能指针明确致力于管理其指针的生命周期。 (不包括不应该单独使用的弱指针)。
对我来说,父子系统与deleteLater
无关,因为系统是直接清理子系统。 deleteLater
的使用与信号槽系统有关。因此,在我看来,您不使用 父子系统 与使用或不使用deleteLater
的选择无关。而你确实使用 信号槽系统。
是的,我明白了。我问的唯一原因是知道如何使用智能指针处理这种情况。如何让对象在插槽被触发之前存活。
更具体地说,我想知道 unique_ptr
或 shared_ptr
是否有办法生存,直到信号被触发然后被删除。
【参考方案1】:
如果不将apiRequest
对象存储在某个容器中,直到触发requestFinished
,我认为您无法使用C++ 智能指针解决此问题。
也许另一种方法是创建一个ApiRequest::finished()
方法用作信号的receiver
,然后将this
传递给ApiRequest
的构造函数,以便finished()
可以调用MyClass::onApiRequestFinished()
,然后在onApiRequestFinished()
退出后让finished()
调用delete this
,例如:
void MyClass::makeRequest()
ApiRequest* apiRequest = new ApiRequest(this);
apiRequest->makeRequest();
void MyClass::onApiRequestFinished()
// do my stuff
...
ApiRequest::ApiRequest(MyClass *cls)
: m_cls(cls)
connect(this, &ApiRequest::requestFinished, this, &ApiRequest::finished);
void ApiRequest::finished()
m_cls->onApiRequestFinished();
delete this;
不确定这在 Qt 中是否可行,但也许值得一试。
【讨论】:
但这并没有提供比我当前更好的解决方案,并且仅将ApiRequest
与MyClass
联系起来。在我的最后一个插槽中,我可以通过 auto apiRequest = qobject_cast<ApiRequest*>(sender());
获取 ApiRequest
对象,然后在其上调用 deleteLater()
。以上是关于智能指针作为 QObject::deleteLater() 的替代品的主要内容,如果未能解决你的问题,请参考以下文章
智能指针作为条件:if (p) 和 if (i.get()) 是不是等效?