Qt文檔閱讀筆記-QScopedPointer解析及實例

當指針超出範圍後就會刪除被引用的對象。
與QPointer不同,他可以在任意類型中使用(QPointer只能在identity type中使用)
4個不同的清除類
        1. QScopedPointerDeleter
  2. QScopedPointerArrayDeleter
  3. QScopedPointerArrayDeleter
  4. QScopedPointerDeleteLater
如下例子:QScopedPointer<int, QScopedPointerArrayDeleter<int>> intArrayPointer(new int(100));
 
在如下幾個方面用得比較多:
異常
使代碼簡潔
通常用於刪除動態分配的變量。
 
 

QPointerQScopedPointer基本上用用動態分配的對象,在範圍外自動進行釋放,這個範圍是通過{}包起來的,也就是函數的生存週期。

如下面這個原始代碼:

void myFunction(bool useSubClass)
  {
      MyClass *p = useSubClass ? new MyClass() : new MySubClass;
      QIODevice *device = handsOverOwnership();

      if (m_value > 3) {
          delete p;
          delete device;
          return;
      }

      try {
          process(device);
      }
      catch (...) {
          delete p;
          delete device;
          throw;
      }

      delete p;
      delete device;
  }

使用了QScopedPointer後:

void myFunction(bool useSubClass)
  {
      // assuming that MyClass has a virtual destructor
      QScopedPointer<MyClass> p(useSubClass ? new MyClass() : new MySubClass);
      QScopedPointer<QIODevice> device(handsOverOwnership());

      if (m_value > 3)
          return;

      process(device);
  }

帶限定符的C++指針使用QScopedPointer:

const QWidget *const p = new QWidget();
      // is equivalent to:
      const QScopedPointer<const QWidget> p(new QWidget());

      QWidget *const p = new QWidget();
      // is equivalent to:
      const QScopedPointer<QWidget> p(new QWidget());

      const QWidget *p = new QWidget();
      // is equivalent to:
      QScopedPointer<const QWidget> p(new QWidget());

自定義清空

相當於delete操作QScopedPointerDeleter

相當於delete []操作QScopedPointerArrayDeleter

相當於free操作QScopedPointerPodDeleter

相當於deleteLater操作QScopedPointerDeleteLater

代碼如下:

// this QScopedPointer deletes its data using the delete[] operator:
  QScopedPointer<int, QScopedPointerArrayDeleter<int> > arrayPointer(new int[42]);

  // this QScopedPointer frees its data using free():
  QScopedPointer<int, QScopedPointerPodDeleter> podPointer(reinterpret_cast<int *>(malloc(42)));

  // this struct calls "myCustomDeallocator" to delete the pointer
  struct ScopedPointerCustomDeleter
  {
      static inline void cleanup(MyCustomClass *pointer)
      {
          myCustomDeallocator(pointer);
      }
  };

  // QScopedPointer using a custom deleter:
  QScopedPointer<MyCustomClass, ScopedPointerCustomDeleter> customPointer(new MyCustomClass);

下面是在類聲明的時候要注意的問題:

class MyPrivateClass; // forward declare MyPrivateClass

  class MyClass
  {
  private:
      QScopedPointer<MyPrivateClass> privatePtr; // QScopedPointer to forward declared class

  public:
      MyClass(); // OK
      inline ~MyClass() {} // VIOLATION - Destructor must not be inline

  private:
      Q_DISABLE_COPY(MyClass) // OK - copy constructor and assignment operators
                               // are now disabled, so the compiler won't implicitely
                               // generate them.
  };

運行截圖如下:

代碼如下:

#ifndef CLASSA_H
#define CLASSA_H

#include <QString>
#include <QDebug>

class ClassA;

struct ClassACustomDeleter{

    static inline void cleanup(ClassA *p){

        qDebug() << "static inline void cleanup(ClassA *p) called";
        delete p;
    }
};

class ClassA
{
public:
    ClassA();
    ~ClassA();
    const QString &getStr();
    const int &getValue();

private:
    QString m_str;
    int m_value;
};

#endif // CLASSA_H

ClassA.cpp

#include "ClassA.h"
#include <QDebug>

ClassA::ClassA() : m_str("字符串"), m_value(10)
{

}

ClassA::~ClassA()
{
    qDebug() << "ClassA::~ClassA() called";
}

const QString &ClassA::getStr()
{
    return m_str;
}

const int &ClassA::getValue()
{
    return m_value;
}

main.cpp

#include <QCoreApplication>
#include <QDebug>
#include <QScopedPointer>
#include "ClassA.h"

void normalFunction(){

    ClassA *a = new ClassA;
    try {

        if(0 == 0){

            throw "error";
        }
    }
    catch(char const *err) {

        qDebug() << err;
        delete a;
        return;
    }

    //want to do sth
    //...
    //well
    delete a;
}

void usingQScopedFunction(){

    QScopedPointer<ClassA> p(new ClassA);
}

void usingQScopedCustomFunction(){

    QScopedPointer<ClassA, ClassACustomDeleter> p(new ClassA);
}


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

    normalFunction();
    qDebug() << "------------華麗的分割線------------";
    usingQScopedFunction();
    qDebug() << "------------華麗的分割線------------";
    usingQScopedCustomFunction();

    return a.exec();
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章