QT 指针 源码解析
来源:互联网 发布:java vector实现原理 编辑:程序博客网 时间:2024/04/30 09:56
1、QPointer指针
1.1 QPointer的误区
查看QT的一些书籍会发现,QPointer被认为是一个智能指针,而我们
所理解的智能指针应该如下:
//parent为父对象,可能为空
QPointer<CTest> pTest= new CTest(parent);
之后,对pTestClass是不用delete的了。实际上查看代码后会发现QPointer并非如此的,QPointer的构造和析构只是分别执行了addGuard和removeGuard,再看下去会发现add和remove只是从一个Hash表中删除了CTest这个对象,但是不会delete它。如果我们不断的使用QPointer,而不析构它,实际上会出现内存泄露的,特别是parent为NULL的时候,是没有任何操作会帮你析构new出来的对象的
如果parent不为空呢?
1.2 QT Parent析构问题
如上中parent不为空,或则我们在界面中new QPushButton(parent)等信息,parent会在析构的时候,帮我们析构所有child。但是parent如果没有析构,我们不断new QPushButton(this),程序也会出现内存不断增长的情况,我们不能完全依赖于QT 的Parent机制来解决内存问题
那QT有没有如C++ auto_ptr的智能指针呢
1.3 QScopedPointer
这就是一个我们理解的真正的智能指针了,对象使用完毕,它会帮我们执行delete,方式与QPointer一样,按照如下使用即可
QScopedPointer<CTest> pTest= new CTest(parent); QScopedPointer与auto_ptr的区别在于所有权的转移问题,QScopedPointer刻意设计为不可转移所有权,auto_ptr设置转移后,原指针会失效,会引起误操作。这也是auto_ptr设计的不好的地方,另外要支持所有权的转移并且安全就要用到引用计数的指针了,QT帮我们提供了QSharedPointer。
1.4 QPointer真正实用的地方
C++中指针有个如下问题
CTest* pTest1 = new CTest;
CTest* pTest2 = pTest1;
如果在其它地方
delete pTest1;
我们知道,为了防止野指针,会delete后执行如下语句
pTest1 = NULL,再次使用会判断pTest1是否为空。
可是pTest2怎么办?另外如果有很多pTest3,pTest4怎么办?
QPointer提出了解决此问题的方法,这也是基于所有QT对象都继承自QObject的原因,pTest1析构时会执行到QObject的析构函数中,我们看到析构函数会有如下代码
if (d->hasGuards && !d->isWidget) {
// set all QPointers for this object to zero - note that
// ~QWidget() does this for us, so we don't have to do it twice
QObjectPrivate::clearGuards(this);
}
QT会判断是否有Guard,即我们前面QPointer中执行的addGuard,如果有,会执行clearGuards,即帮我们把pTest2等都置空,这样各处都能使用QPointer::IsNull()来判断并且安全的使用了
1.5 多提一句,涉及到指针离不开上面的几种,而boost也帮我们提供了解决方案,我们应该越来越少的使用delete操作了。从内存泄露中解脱出来
Boost::scoped_pt与QScopedPointer一样
Boost::shared_ptr与QShardPointer一样
- QT 指针 源码解析
- Qt源码解析(1)
- QT源码解析
- QT Layout源码解析
- QT源码解析
- QT源码解析 文章索引
- QT源码解析 文章索引
- QT 事件机制 源码解析
- QT拖拽源码解析
- 智能指针 auto_ptr 源码解析
- QT源码解析(九)解析QDateTime
- Qt d指针简单实现及解析
- Qt d指针简单实现及解析
- QT View及Model源码解析
- Qt信号-槽源码解析(二)
- Qt信号-槽源码解析(一)
- QT View及Model源码解析
- C++ 只能指针 auto_ptr 原理 解析 源码
- RAC ORACLE 内存不够问题
- java.lang.IllegalArgumentException: <session-config> element is limited to 1 occurrence
- Dataguru 优惠码
- 特殊字符在XML中的Unicode编码
- Storm集群部署
- QT 指针 源码解析
- web.xml中<security-constraint>和四种认证类型
- MSSQL如何查看当前数据库的连接数
- Linux stat函数讲解
- HttpClient教程(六)
- VS2013快捷键大全
- 下载android源码
- 关于几种二分的想法
- hibernate.current_session_context_class属性配置