Qt——智能指针实战

目录

前言

智能指针的使用,对很多程序员来说,都算是比较高深的存在,但又老是感觉这是一个值得去掌握,且需要去掌握的东西,所以,这次下定决心,来掌握一下Qt的智能指针的使用,当然,最常用的肯定是QSharedPoint这个了,其他的应该也就是顺带着讲一讲,并且,普及一些知识,从而让自己的能力更上一层楼把。

正文

一、理论介绍

1、QPointer

QPointer是Qt提供的空安全的智能指针,它用于解决悬挂指针的问题。QPoint在对象被删除后,会自动被设置为nullptr,避免访问已经无效的对象,它类似于普通指针,但提供了一些安全检查。

总结来说就是:

当你创建一个对象,然后使用QPointer指向这个对象,若出现delete 了那个对象,但是未将那个对象置空的情况的话,判断的时候,直接判断QPointer对象,就可以知道到底是真的删除了那个对象,还是假的删除了。避免了悬挂指针的问题。

QPoint 充当一个管家的角色,对真正的指针做好判断。

2、QScopedPoint

QScopedPoint 是Qt提供的独占式的智能指针,用于管理动态分配的对象,QScopedPoint 在超出作用域时,自动删除对象,确保对象在不再需要时,被正确释放。

3、QSharedPoint

QSharedPoint 是Qt提供的共享引用计数的指针,可用于管理动态分配的对象。它通过引用计数跟踪对象的引用次数,当引用次数归零时,会自动删除对象。可以通过多个QSharedPoint共享同一个对象,对象会在最后一个引用者释放它时,才会被删除。

4、QWeakPoint

QWeakPoint 是Qt提供的弱引用智能指针,用于解决循环引用的问题。QWeakPoint 可以引用由QSharedPoint管理的对象,但不会增加引用计数的次数。QWeakPoint需要转换成QSharedPoint才能访问对象,当引用计数为0时,访问会失败。

二、实战演练

1、QPoint

MyClass.h

c 复制代码
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QPointer>
#include <QDebug>
class MyClass : public QObject
{
    Q_OBJECT

public:
    MyClass(const QString& name): m_name(name)
    {
        qDebug() << "MyClass 构造函数,名称为:"<<m_name;
    }

    ~MyClass()
    {
        qDebug() << "MyClass 析构函数,名称为:"<<m_name;
    }

    QString getName() const {return m_name;}

private:
    QString m_name;
};

#endif // MYCLASS_H

main.cpp

c 复制代码
#include <QCoreApplication>
#include <QPointer>
#include <QDebug>
#include "MyClass.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MyClass *obj = new MyClass("test");

    QPointer<MyClass> myObject(obj);

    if (myObject)
    {
        qDebug() << "对象存在,名称为" << myObject->getName();
    }
    else
    {
        qDebug() << "对象不存在";
    }

    delete obj;
    if (myObject)
    {
        qDebug() << "对象存在,名称为" << myObject->getName();
    }
    else
    {
        qDebug() << "对象不存在";
    }

    return a.exec();
}

2、QScopedPoint

c 复制代码
void MainWindow::TestQScopedPointer()
{
    useResource();
    qDebug() << "useResource 函数执行完毕";
}

void MainWindow::useResource()
{
    QScopedPointer<Resource> scopedResource(new Resource());;
    //执行一些操作,使用资源
    qDebug() << "---> 使用资源 ";
}

QScopedPoint 在适当的时候,会自动调用析构函数释放资源。

结果:

c 复制代码
Resource 构造函数
---> 使用资源 
Resource 析构函数
useResource 函数执行完毕

3、QSharedPoint

a、示例一
c 复制代码
#include <QSharedPointer>
#include <QScopedPointer>
#include <QDebug>
// 假设的图形对象类
class GraphicObject {
public:
    GraphicObject() { qDebug() << "GraphicObject created"; }
    ~GraphicObject() { qDebug() << "GraphicObject destroyed"; }
    // 具体的图形对象操作
};
// 文档对象类
class Document {
public:
    Document() { qDebug() << "Document created"; }
    ~Document() { qDebug() << "Document destroyed"; }
    // 添加图形对象到文档
    void addGraphicObject(QSharedPointer<GraphicObject> graphicObject) {
        graphicObjects.append(graphicObject);
    }
    // 具体的文档操作
private:
    QList<QSharedPointer<GraphicObject>> graphicObjects;
};
int main() {
    // 使用 QSharedPointer 确保图形对象的自动释放
    QSharedPointer<GraphicObject> graphicObject(new GraphicObject);
    // 使用 QScopedPointer 确保文档对象的自动释放
    QScopedPointer<Document> document(new Document);
    // 将图形对象添加到文档
    document->addGraphicObject(graphicObject);
    // 注意:在这里,graphicObject 和 document 会在适当的时候自动释放
    return 0;
}
b、示例二
c 复制代码
#ifndef MYSHAREDCLASS_H
#define MYSHAREDCLASS_H
#include <QPointer>
#include <QDebug>
class MySharedClass : public QObject
{
    Q_OBJECT

public:
    MySharedClass(int value): m_iValue(value)
    {
        qDebug() << "MySharedClass 构造函数,值为:"<<m_iValue;
    }

    ~MySharedClass()
    {
        qDebug() << "MySharedClass 析构函数,值为:"<<m_iValue;
    }

    void setValue(int value)
    {
        m_iValue = value;
    }

    int getValue() const
    {
        return m_iValue;
    }

private:
    QString m_name;
    int m_iValue;
};
#endif // MYSHAREDCLASS_H
c 复制代码
void MainWindow::TestSharedPointer()
{
    //先用一个智能指针指向一个对象
    QSharedPointer<MySharedClass> pointer1(new MySharedClass(10));

    {
        //通过复制构造函数 让引用+1
        QSharedPointer<MySharedClass> pointer2 = pointer1;

        qDebug() << "---> pointer1 的值:"<<pointer1->getValue();
        qDebug() << "---> pointer2 的值"<<pointer2->getValue();

        //实际上都是对同一个对象进行操作
        pointer2->setValue(20);
        qDebug() << "--->w pointer1 的值:"<<pointer1->getValue();
        qDebug() << "--->w pointer2 的值"<<pointer2->getValue();
    }

    qDebug() << "--->w pointer1 的值:"<<pointer1->getValue();
    //之后,智能指针超出作用域之后,会自动析构掉
}

4、QWeakPoint

c 复制代码
#ifndef MYWEAKCLASS_H
#define MYWEAKCLASS_H

#include <QSharedPointer>
#include <QWeakPointer>
#include <QDebug>

class ObjectB;

class ObjectA
{
public:
    ObjectA(const QString& name) : m_name(name){}
    ~ObjectA()
    {
        qDebug() << "objectA 析构函数,名称为:"<<m_name;
    }

    void setObjectB(const QSharedPointer<ObjectB> &objectB)
    {
        m_objectB = objectB;
    }
private:
    QString m_name;
    QWeakPointer<ObjectB> m_objectB;
};

class ObjectB
{
public:
    ObjectB(const QString& name): m_name(name){}

    ~ObjectB()
    {
        qDebug() << "Object 析构函数,名称为:"<<m_name;
    }

    void setObjectA(const QSharedPointer<ObjectA> &objectA)
    {
        m_objectA = objectA;
    }

private:
    QString m_name;
    QSharedPointer<ObjectA> m_objectA;
};

#endif // MYWEAKCLASS_H
c 复制代码
void MainWindow::TestWeakPointer()
{
    QSharedPointer<ObjectA> objectA(new ObjectA("ObjectA"));
    QSharedPointer<ObjectB> objectB(new ObjectB("ObjectB"));

    objectA->setObjectB(objectB);
    objectB->setObjectA(objectA);

    qDebug() << "程序结束";
}

END、总结的知识与问题

参考

1、[Qt杂谈8.浅谈Qt智能指针那些事](https://www.cnblogs.com/luoxiang/p/17927569.html)

相关推荐
強云33 分钟前
界面架构- MVP(Qt)
qt·架构
我命由我1234537 分钟前
Spring Boot 自定义日志打印(日志级别、logback-spring.xml 文件、自定义日志打印解读)
java·开发语言·jvm·spring boot·spring·java-ee·logback
徐小黑ACG2 小时前
GO语言 使用protobuf
开发语言·后端·golang·protobuf
0白露3 小时前
Apifox Helper 与 Swagger3 区别
开发语言
Tanecious.4 小时前
机器视觉--python基础语法
开发语言·python
叠叠乐4 小时前
rust Send Sync 以及对象安全和对象不安全
开发语言·安全·rust
Tttian6225 小时前
Python办公自动化(3)对Excel的操作
开发语言·python·excel
独好紫罗兰6 小时前
洛谷题单2-P5713 【深基3.例5】洛谷团队系统-python-流程图重构
开发语言·python·算法
闪电麦坤957 小时前
C#:base 关键字
开发语言·c#
Mason Lin7 小时前
2025年3月29日(matlab -ss -lti)
开发语言·matlab