QT学习总结--智能指针

zhy

发布于 2020.04.04 12:46 阅读 3107 评论 0

  在上一篇文章中提到了我有时候会忘记删除指针,导致程序异常终止的问题,qt中存在智能指针,可以帮助自动我们销毁指针。

 

  什么是智能指针呢? 智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象 。qt中最常用的智能指针是 QSharedPointer 和 QScopedPointer 两个类。

 

  QSharedPointer :

      这是一个共享指针,计数类型的指针,他在内部对拥有的内存资源进行引用计数 ,当资源数为0时,就会自动释放内存。使用方法:

QSharedPointer<MyObject> obj =
        QSharedPointer<MyObject>(new MyObject);

  

 

QScopedPointer :

      QScopedPointer是范围指针,具有更严格的所有权,并且不能转让,一旦获取了对象的管理权,你就无法再从它那里取回来 , 只要出了作用域,指针就会被自动删除 。在我们需要函数返回值的时候, 可以使用QScopedPointer::take()返回对象指针 , 对象所有权会转移给调用函数的对象。

MyClass myFunction(bool useSubClass)
 {
     QScopedPointer<MyClass> p(useSubClass ? new MyClass() : new MySubClass);
     
     return p->take();
 }

 

QScopedArrayPointer :

     专门处理数组的指针,用法和QScopedPointer一样,超出作用域会自动删除指针。

 

QPointer :

    这个类与其他指针不同,并不会自动删除,delete()需要手动调用, QPointer 的作用就是在调用delete后将指针设置为NULL,避免野指针的出现。

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

    QPointer<QLabel> pLabel = new QLabel() ;
    delete pLabel;
    if(pLabel){
        qDebug()<< "pLabel is not null";
    }
    else{
        qDebug()<< "pLabel is null";
    }
    return a.exec();
}

//输出结果
pLabel is null

 

    我们在平时的时候可以灵活运用智能指针来替代普通指针,省去必要的麻烦,减少手动delete的次数。但是不建议普通指针和智能指针混用,可能会出现二次析构的情况。

   在使用智能指针时由于Qt的QObject对象树系统, 当父亲销毁的时候,会先销毁它的孩子,之后智能指针会自动清理进行二次删除,导致程序崩溃的问题,目前已经被QT官方解决。