智能指针作为 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_ptrshared_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 中是否可行,但也许值得一试。

【讨论】:

但这并没有提供比我当前更好的解决方案,并且仅将ApiRequestMyClass 联系起来。在我的最后一个插槽中,我可以通过 auto apiRequest = qobject_cast<ApiRequest*>(sender()); 获取 ApiRequest 对象,然后在其上调用 deleteLater()

以上是关于智能指针作为 QObject::deleteLater() 的替代品的主要内容,如果未能解决你的问题,请参考以下文章

工程实践:到底要不要使用智能指针

工程实践:到底要不要使用智能指针

智能指针作为条件:if (p) 和 if (i.get()) 是不是等效?

StrBlob类——智能指针作为成员

我可以在 C++ Actor Framework 中使用 C++11 智能指针作为消息返回类型吗?

指针能作为引用参数吗?