这是一个非常简单的入门过程,你应该熟悉它_
#include QApplication#include QLabelint main(int argc, char *argv[]){QApplication app(argc, argv);QLabel *label=new QLabel('Hello Dbzhang800!');label-show();return app.exec ();}
在《从Qt的delete开始》一文中,我们提到这个程序存在内存泄漏(没有调用析构函数),当时给出了三种解决方案:
将标签对象分配到堆栈而不是堆
将标签位Qt:WA_DeleteOnClose 设置为标签
自己调用delete删除通过new分配到堆的标签对象
笔记:
智能指针
为了管理内存等资源,C++程序员通常使用RAII(资源获取即初始化)机制:在类的构造函数中申请资源,然后使用它们,最后在析构函数中释放资源。
如果没有智能指针,程序员必须保证新对象能够在正确的时间被删除,并且到处写异常捕获代码来释放资源,而智能指针总是能够退出作用域(无论是正常进程还是例外)。调用delete来销毁堆上动态分配的对象。
让我们看一下Qt智能指针家族:
笔记:
MSVC2010 和GCC g++ 4.3 支持C++0x
MSVC2008 sp1 和GCC g++ 4.0 支持tr1
有了这些东西,我们就可以轻松改造之前的示例(只需更改一行):
std:auto_ptrQLabel标签(new QLabel('你好Dbzhang800!'));根据您使用的Qt 版本和C++ 编译器的支持级别,您可以选择:
如何翻译QScopedPointerstd:unique_ptrQSharedPointerstd:shared_ptrstd:tr1:shared_ptrQPointer?我不确定,请用英文保存。
QPointer 类是一个模板类,提供保护
指向QObject 的指针。
用法:一个受保护的指针QPointer,其行为类似于常规指针T *
特点:当它指向的对象(T必须是QObject及其派生类)被销毁时,会自动设置为NULL。
注意:被守护的对象被破坏时,不会自动销毁。
目的:当您需要保存指向其他人拥有的QObject 对象的指针时,这很有用
一个例子:
QPointerQLabel label=new QLabel;label-setText('Status:');if (label)label-show();
如果删除.部分中的对象,label 将自动设置为NULL,而不是悬空的野指针。
QPointer是Qt对象模型的核心机制之一。请注意与其他智能指针的区别。
std:auto_ptr
对此没什么好说的。
多个auto_ptr不能指向同一个对象! (当auto_ptr被销毁时,它指向的对象会被自动删除,所以该对象会被删除多次)
智能指针不能指向数组(因为它们的实现调用的是delete而不是delete[])
智能指针不能用作容器类的元素。
在C++0x中,不再推荐使用auto_ptr,将来应该由其他三个智能指针代替。
QScopedPointer 与std:unique_ptr
它们在概念上应该是相同的。下面不做区分:
这是一个与auto_ptr非常相似的智能指针。它包装了new操作符在堆上分配的动态对象,确保动态创建的对象可以随时被正确删除。但其所有权比较严格,不能转让。一旦获得对象的管理权限,就无法收回。
QScopedPointer 和std:unique_ptr 都有一个好名字,它向代码读者传达了一个明确的信息:这个智能指针只能在这个范围内使用,并且不想被转移。因为它的复制构造和赋值操作是私有的,所以我们可以比较QObject 及其派生类的对象。
用法(来自Qt手册):
考虑没有智能指针的情况,
void myFunction(bool useSubClass){MyClass *p=useSubClass ? new MyClass() : new MySubClass;QIODevice *device=handOverOwnership();if (m_value 3) {delete p;delete device;return;}try {process(device) ;}catch (.) {delete p;delete设备;抛出;}删除p;删除设备;}
我们在异常处理语句中多次写入delete语句,稍有不慎就可能导致资源泄漏。使用智能指针后,我们可以简化这些异常处理语句:
void myFunction(bool useSubClass){QScopedPointerMyClass p(useSubClass? new MyClass() : new MySubClass);QScopedPointerQIODevice device(handsOverOwnership());if (m_value 3)return;process(device);} 另外,我们最初的示例,这也是使用这两个指针的最佳场合(它们指向的对象在离开主函数作用域时将会被销毁)。
注意:因为复制构造和赋值操作是私有的,所以它具有与auto_ptr 不能用作容器元素相同的“缺陷”——。
QSharedPointer 与std:shared_ptr
QSharedPointer 和std:shared_ptr 的行为最接近原始指针,是最像指针的“智能指针”,其应用范围比前面提到的更广泛。
QSharedPointer 与QScopedPointer 一样,包装了new 运算符在堆上分配的动态对象,但它实现了引用计数智能指针,可以自由复制和分配,并在任何地方共享。当没有代码使用它时(参考包装的动态分配的对象,只有当计数达到0时才会被删除)。 shared_ptr也可以安全地放入标准容器中,并弥补了std:auto_ptr和QScopedPointer由于传输语义而无法使用指针作为容器元素的缺点。
QWeakPointer 和std:weak_ptr
Q共享数据指针
Q显式共享数据指针
这是一个使用QSharedData 实现显式共享的便捷工具。
继续上一个员工的示例:
#include 'employee.h'int main(){Employee e1(1001, 'Albrecht Durer');Employee e2=e1;e1.setName('Hans Holbein');}
标签:
用户评论
刚刚开始学Qt,智能指针这部分有点难懂,希望能有详细的例子。
有19位网友表示赞同!
学了一段时间Qt了,智能指针是必须掌握的,希望作者能深入浅出地讲解。
有8位网友表示赞同!
智能指针在Qt中的应用真的很妙,但感觉代码复杂度增加了。
有18位网友表示赞同!
智能指针在Qt中的安全性确实很有优势,但有时候管理起来也相当头疼。
有12位网友表示赞同!
Qt智能指针的学习让我对C++指针有了更深的理解,谢谢分享。
有8位网友表示赞同!
看了教程,感觉Qt智能指针和C++的智能指针有点区别,能详细解释一下吗?
有5位网友表示赞同!
智能指针在Qt中的应用场景非常多,但有时候忘记怎么用,希望有更多实例。
有17位网友表示赞同!
学智能指针的时候,总是记不住各种构造函数,有没有什么好方法?
有20位网友表示赞同!
Qt智能指针的内存管理真的很强大,但有时候觉得太复杂了。
有10位网友表示赞同!
智能指针在Qt中的应用让我对编程有了新的认识,感谢作者分享。
有8位网友表示赞同!
Qt智能指针的学习让我对C++有了更深的兴趣,希望有更多深入的内容。
有15位网友表示赞同!
智能指针在Qt中的应用让我意识到内存管理的重要性,谢谢作者的提醒。
有6位网友表示赞同!
学智能指针的过程中,发现Qt的文档不是很完善,有没有推荐的学习资源?
有12位网友表示赞同!
Qt智能指针的学习让我对C++指针的理解更加清晰,但感觉还是有点乱。
有20位网友表示赞同!
智能指针在Qt中的应用让我对编程有了新的认识,希望有更多实战案例。
有18位网友表示赞同!
学智能指针的时候,发现Qt的智能指针和C++的智能指针有一些不同,能否详细说明一下?
有11位网友表示赞同!
Qt智能指针的学习让我对编程有了更深的理解,但感觉还是有很多疑惑。
有16位网友表示赞同!
智能指针在Qt中的应用让我对编程有了新的认识,希望有更多关于Qt智能指针的讨论。
有14位网友表示赞同!
学Qt智能指针的过程中,感觉代码写起来更简洁了,但有时候还是会忘记怎么用。
有9位网友表示赞同!