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. JavaFX 之窗口大小自由拉伸(四)

    一.问题场景 同样的,隐藏掉窗体的默认标题栏也会导致窗体大小自由拉伸功能的失效. 二.解决思路 判断鼠标在窗体的位置,改变鼠标样式,给窗体组件添加拖拽事件监听器,根据鼠标移动位置改变窗体大小. 三.代 ...

  2. 各大互联网公司2014前端笔试面试题–HTML,CSS篇

    Html篇: 1.你做的页面在哪些流览器测试过?这些浏览器的内核分别是什么? IE: trident内核 Firefox:gecko内核 Safari:webkit内核 Opera:以前是presto ...

  3. linux mount / umount 命令的基本用法 及 开机自动挂载

    格式:mount [-参数] [设备名称] [挂载点] 其中常用的参数有: -a 安装在/etc/fstab文件中类出的所有文件系统. -f 伪装mount,作出检查设备和目录的样子,但并不真正挂载文 ...

  4. kafka 经典教程

    一.基本概念 介绍 Kafka是一个分布式的.可分区的.可复制的消息系统.它提供了普通消息系统的功能,但具有自己独特的设计. 这个独特的设计是什么样的呢? 首先让我们看几个基本的消息系统术语: Kaf ...

  5. Appium+python自动化25-windows版appium_desktop_V1.7.1

    appium_desktop_v1.2.6 1.appium_desktop在github上最新下载地址:releases/tag/v1.2.6 2.下载后傻瓜式安装,然后启动appium,这个界面跟 ...

  6. POJ 3276 Face The Right Way(反转)

      Face The Right Way Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6038   Accepted: 2 ...

  7. 简单的SOCKET例子

    定义实例socket.socket(),如果括号里不写参数,默认为IPV4+TCP 我们猜测客户端的完整代码如下: 同样我们猜测服务端的代码如下: 实际上运行客户端代码: 说明在py3里,网络编程发送 ...

  8. Zabbix 添加 WEB 监控

    添加 WEB Monitorings Web Monitoring是用来监控web程序的,可以监控到web程序的下载速度.返回码及响应时间,还支持把一组连续的web动作作为一个整体来监控. 下面我们以 ...

  9. sql sever数据库常用的执行语句

    --使用master数据库use master --创建数据库文件create database 数据库名字 on( name=, --逻辑名称 filename= .ndf, --数据文件物理路径名 ...

  10. 为什么 ReactJS 不适合复杂的前端项目?

    问题一:ReactJS组件难以在复杂交互页面中复用 ReactJS中的最小复用单位是组件.ReactJS的组件比AngularJS的Controller和View 要轻量些. 每个组件只需要前端开发者 ...