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();
}