QT智能指针实例

  QT智能指针实例

    一直没有合适的项目场景来使用智能指针,现在出现了这么一个 场景
    在A类中New了一份内存,并且使用成员函数指针 对此内存进行管理;在B类中需要经常使用此内存做一些逻辑处理。现在希望的是: 当在A类中释放此内存块时,对应的B类中指针直接变为空指针。UML类图如下所示:
    A类即Cppbackend;B类即LayerRander的m_layerPath中的LayerPath;每当Cppbackend中new一份内存被删除时,期望类LayerPath中m_ptrCli变成空指针;
    实现:
1)直接创建QSharedPointer<CliModelAndSupport> ptr并且设置一个删除器doDeleteCliPtrLater;由QSharedPointer来管理CliModelAndSupport的内存;
CliModelAndSupport* CppBackend::createCliFile(const QString &filePath, bool isCopy)
{
    QSharedPointer<CliModelAndSupport> ptr = QSharedPointer<CliModelAndSupport>(new CliModelAndSupport(filePath), doDeleteCliPtrLater);
    if (m_fCommonThickness > 0)
    {
        ptr->setCommonThickness(m_fCommonThickness);
    }
    connect(ptr.data(), SIGNAL(finishParsingTotalLayers(bool, QString)), this, SLOT(onFinishParsingTotalLayers(bool, QString)));
    QQmlEngine::setObjectOwnership(ptr.data(), QQmlEngine::CppOwnership);
    m_ModelInfolist.push_back(ptr);
    return ptr.data();
}
// 智能指针删除器Deleter deleter  //QSharedPointer(X *ptr, Deleter deleter)
static void doDeleteCliPtrLater(CliModelAndSupport* ptrCli)
{
    ptrCli->deleteLater();
}
2)再将m_ModelInfolist中的QSharedPointer<CliModelAndSupport>转化为QWeakPointer<CliModelAndSupport>,使之使用一份弱引用;
    // 将此模型文件设置给m_ptrLayerRanderer,使之呈现模型对应的层数据
    for (QVector<QSharedPointer<CliModelAndSupport> >::iterator itor = m_ModelInfolist.begin(); itor != m_ModelInfolist.end(); itor++)
    {
        if ((*itor).data() == cli)
        {
            m_ptrLayerRanderer->addCliInfo(QWeakPointer<CliModelAndSupport>(*itor));
            m_ptrLayerRanderer->setLayerIndex(currentLayerIndex);
            m_ptrLayerRanderer->update();  // 直接更新下,防止由于层索引相同导致未刷新
        }
    }

此时对应的引用计数如下图,即强引用1次,弱引用2次(强智能指针占1次,弱智能占1次):



3)当要删除m_ModelInfolist对应的内存时,直接调用QSharedPointer的成员函数clear();在内存删除时,QSharedPointer自动调用删除器doDeleteCliPtrLater去做删除工作,你可以在删除器做额外的逻辑处理;

void CppBackend::removeModel()
{
    QString modelName = m_ptrLayerRanderer->getSelectedModelName();
    // 删除数据
    for (QVector<QSharedPointer<CliModelAndSupport> >::iterator itor = m_ModelInfolist.begin(); itor != m_ModelInfolist.end(); itor++)
    {
        if ((*itor)->getFileName() == modelName)
        {
            (*itor).clear();
            m_ModelInfolist.erase(itor);
            break;
        }
    }
    // 删除模型
    m_ptrLayerRanderer->removeSelectedModel();
    m_ptrLayerRanderer->update();

    // 更新LayerSilder的总层数,并将当前层设置为第1层
    int iLayerCount = 0;
    for (QVector<QSharedPointer<CliModelAndSupport>>::iterator itor = m_ModelInfolist.begin(); itor != m_ModelInfolist.end(); itor++)
    {
        if ((*itor)->layerCount() > iLayerCount)
        {
            iLayerCount = (*itor)->layerCount();
        }
    }

    emit resetLayerSilder(iLayerCount);
}
此时对应的引用计数如下图,可以明确看到m_ptrCli为NULL,并且若引用计数为1;

4)最后,在LayerPath类的析构函数中 将m_ptrCli删除(m_ptrCli.clear();)

总结

    使用强智能指针和弱智能指针能够方便的管理内存,如果将强智能指针清空(clear()),则其弱引用可以自动判断出其内存已被删除,弱引用自动变为NULL,不在需要程序员进行手动删除指针。



已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页