QScopedpointer

detailed description

the QScopedpointer class stores a pointer to a dynamically allocated object, and deletes it upon destruction.

managing heap allocated objects manually is hard and error prone, with the common result that code leaks memory and is hard to maintain. QScopedpointer is a small utility class that heavily simplifies this by assigning stack-based memory ownership to heap allocations, more generally called resource acquisition is initialization(raii).

QScopedpointer guarantees that the object pointed to will get deleted when the current scope disappears.

consider this function which does heap allocations, and has various exit points:

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

it's encumbered by the manual delete calls. with QScopedpointer, the code can be simplified to:

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

the code the compiler generates for QScopedpointer is the same as when writing it manually. code that makes use of delete are candidates for QScopedpointer usage (and if not, possibly another type of smart pointer such as QSharedPointer). QScopedpointer intentionally has no copy constructor or assignment operator, such that ownership and lifetime is clearly communicated.

The const qualification on a regular C++ pointer can also be expressed with a 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());

Custom Cleanup Handlers

Arrays as well as pointers that have been allocated with malloc must not be deleted using delete. QScopedpointer's second template parameter can be used for custom cleanup handlers.

The following custom cleanup handlers exist:

  • QScopedpointerDeleter - the default, deletes the pointer using delete
  • QScopedpointerArrayDeleter - deletes the pointer using delete []. Use this handler for pointers that were allocated with new [].
  • QScopedpointerPodDeleter - deletes the pointer using free(). Use this handler for pointers that were allocated with malloc().
  • QScopedpointerDeleteLater - deletes a pointer by calling deleteLater() on it. Use this handler for pointers to QObject's that are actively participating in a QEventLoop.

You can pass your own classes as handlers, provided that they have a public static function void cleanup(T *pointer).

  // 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);

Forward Declared Pointers

Classes that are forward declared can be used within QScopedpointer, as long as the destructor of the forward declared class is available whenever a QScopedpointer needs to clean up.

Concretely, this means that all classes containing a QScopedpointer that points to a forward declared class must have non-inline constructors, destructors and assignment operators:

  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.
};

Otherwise, the compiler output a warning about not being able to destruct MyPrivateClass.

Related Classed

  • QSharedPointer.

QScopedPointer的更多相关文章

  1. Qt也有垃圾回收(通过QScopedPointer实现),下决心在项目里使用QScopedPointer,省了太多事情了,而且更安全!!

    也谈Qt的垃圾回收 前几天在做代码审核的时候,Kai Uwe Broulik建议使用QScopedPointer来替代手工内存管理,使用后发觉确实节约了不少代码量,我的CHERRY可以延长寿命了!但是 ...

  2. Qt智能指针QPointer, QSharedDataPointer ,QSharedPointer,QWeakPointer和QScopedPointer

    QPointer (4.0) 已经过时,可以被QWeakPointer所替代,它不是线程安全的. QSharedDataPointer (4.0) -- 提供对数据的COPY-ON-WRITE以及浅拷 ...

  3. QPointer更安全,QScopedPointer自动出范围就删除,QSharedDataPointer帮助实现隐式共享

    http://blog.csdn.net/hai200501019/article/details/8474582http://blog.csdn.net/hai200501019/article/d ...

  4. Qt on Android 核心编程

    Qt on Android 核心编程(最好看的Qt编程书!CSDN博主foruok倾力奉献!) 安晓辉 著   ISBN 978-7-121-24457-5 2015年1月出版 定价:65.00元 4 ...

  5. Qt 之 入门例程 (一)

    以 “Hello Qt” 为例,介绍如何建立一个 Qt 工程 . 1  QLabel 例程 QLabel 继承自 QFrame (继承自 QWidget),主要用来显示文本和图片. 1.1  Hell ...

  6. Qt QObject

    [1]Qt的QObject 1.测试代码如下: #include<QApplication> #include<QPushButton> #include<QDebug& ...

  7. QCustomplot使用分享(七) 层(完结)

    一.分层绘制 一直说要讲2.0.0版本,但总是想把1.3.2版本拿出来比较一下,这篇文章也不例外.QCustomPlot2.0.0beta版本比1.3.2release版本有一个很大的改进那就是分层绘 ...

  8. QCustomplot使用分享(六) 坐标轴和网格线

    一.概述 前边已经写了5篇对QCustomPlot的讲解,看过上述的几篇文章后,基本就能做一些简单的使用了,但是如果想要做到高度的控制图表,那么坐标轴将是很重要的一部分,因为坐标轴就是图表的一个参考系 ...

  9. Qt中单例模式的实现(4种方法)

    最简单的写法: 12345 static MyClass* MyClass::Instance(){ static MyClass inst; return &inst;} 过去很长一段时间一 ...

随机推荐

  1. 9.Python安装scrapy教程

     1.在命令行中输入:pip3 install scrapy(pip3是因为本人python版本是3.6),报错如下: 2.解决方法:在https://www.lfd.uci.edu/~gohlke/ ...

  2. golang之交叉编译设置

    俺的环境,os x,目的,生成64位linux的elf文件 直接下载osx的包就可以,不需要特意去下载源码包,我的go目录是~/golang/go cd ~/golang/go/srcGOOS=lin ...

  3. 1045 access denied for user 'root'@'localhost' using password yes

    mysql -u root -p 方法一:  # /etc/init.d/mysql stop  # mysqld_safe --user=mysql --skip-grant-tables --sk ...

  4. python 发红包

    import random li = [] def fahongbao(money,num=6): if money > 0 and num != 1: n = round(random.uni ...

  5. IP 地址 与 DNS

    IP地址转化 192.168.10.1 十进制,点分十进制地址 32位二进制数字序列,四段,八位 十进制与二进制转换00000000 = 000000001 = 2 * 0 = 100000010 = ...

  6. cache的作用

    cache的作用就是第一次请求完毕之后,如果再次去请求,可以直接从缓存里面读取而不是再到服务器端读取. 如果使用jquery,可以使用 cache参数来控制 $.ajax({  url: " ...

  7. 电话号码以185****3547显示demo

    String phone="18678473547"; //String phones = phone.substring(0,phone.length()-(phone.subs ...

  8. cocos2d中的坐标系统

    cocos2d中Layer的默认锚点是left.buttom sprite的锚点设置 setAnchorPoint(cc.p(0.5,0.5)); 默认锚点:中心 setAnchorPoint(cc. ...

  9. Python - 第一个 Django 项目

    Django 的安装: pip3 install django==1.11.11 pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple/ d ...

  10. python socket打造一个定位工具

    前言: 刚刚学习socket,打算后期得学习 怎么写exploit. 原理: 其实很简单,客户端写个爬虫.然后将获取到的IP放入高德地图 在通过socket发送.利用ngrok达到能外网搞事. 准备: ...