Qt QPointer 和 QSharedPointer 使用实例

 

 

在网上查到很多关于Qt 中 QPointer 和 QSharedPointer, 大部分是官方的例子,这里给个实际在对象中使用。

首先介绍一下 QPointer 和 QSharedPointer的简单用法。

QPointer

QPointer can only point to QObject instances. It will be automatically set to nullptr if the pointed to object is destroyed. It is a weak pointer specialized for QObject. 

简单理解为,为指向QObject提供了一层包装,和C++传统指针一样的方法,但可以避免 “野” 指针。可以大胆的使用。

QObject *obj = new QObject;
QPointer<QObject> pObj(obj);
delete obj;
Q_ASSERT(pObj.isNull()); // pObj will be nullptr now

QSharedPointer

A reference-counted pointer. The actual object will only be deleted, when all shared pointers are destroyed. Equivalent to std::shared_ptr.

简单说就是不用了,就释放了。

int *pI = new int;
QSharedPointer<int> pI1(pI);
QSharedPointer<int> pI2 = pI1;
pI1.clear();
// pI2 is still pointing to pI, so it is not deleted
pI2.clear();
// No shared pointers anymore, pI is deleted

综合例子

1.  建立一个person 对象,这里简化只有一个成员 name。

 

Person.h

class Person :  public QObject
{
    Q_OBJECT
public:
    Person(const QString &name, QObject *parent = nullptr);
    virtual ~Person();
    QString name() const;
    void setName(const QString &name);

private:
    QString m_name; // 名字
};

Person.cpp

Person::Person(const QString &name, QObject *parent) : QObject(parent)
{
    m_name = name;
    qDebug() << "create a person: " << m_name;
}


Person::~Person()
{
    qDebug() << "delete a person: " << m_name;
}

QString Person::name() const
{
    return m_name;
}

void Person::setName(const QString &name)
{
    m_name = name;
}

为了更加明白说明时候释放对象,我们建立一个MainWindow类, 下面是代码

 

头文件

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    QList<QPointer<Person>> m_persons;
    QSharedPointer<Person> m_person;

};
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    qDebug() << m_person;
    m_persons.append(new Person("person1"));
    m_persons.append(new Person("person2"));


    QPointer<Person> tmp = new Person("tmp");
    // need delelet tmp
    delete tmp;
    QSharedPointer<Person> sharedPerson(new Person("sharedPerson"));
    m_person = sharedPerson;
}

MainWindow::~MainWindow()
{
    qDebug("call ~Mainwindow");
    // 释放拥有的 children
    qDeleteAll(m_persons);
    m_persons.clear();
    // m_person 被释放,这就是智能指针

}

 

最后的打印结果是

QSharedPointer(QObject(0x0))
create a person:  "person1"
create a person:  "person2"
create a person:  "tmp"
delete a person:  "tmp"
create a person:  "sharedPerson"
call ~Mainwindow
delete a person:  "person1"
delete a person:  "person2"
delete a person:  "sharedPerson"

分析结果, 在使用QPointer 的QList中,释放的时候用QList管理,调用qDeleteAll(), 不调用不会调用person的析构函数,正常使用的QObject对象指针都是有parent的,所以不需要专门调用qDeleteAll。然后为了单独验证QPointer, 专门生成了tmp, 这个必须delete。如果不确定被其他得放释放,调用 tmp.isNull() 判断一下。

m_person 指向了 QSharedPointer<Person>,这个使用就像一个普通的对象一样,都没有调用 m_person.clear(),这样,在多个实例中共享 m_person 就不需要想着哪儿忘了释放了。

具体例子我打包放到 https://download.csdn.net/download/luodanzhi/10772842

 

参考:

[Qt内存管理(三) Qt的智能指针](https://blog.csdn.net/yao5hed/article/details/81092152)

  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值