Qt 智能指针学习

评论

这是一个非常简单的入门过程,你应该熟悉它_

#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,而不是悬空的野指针。

Qt智能指针学习

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位网友表示赞同!

〆mè村姑

学了一段时间Qt了,智能指针是必须掌握的,希望作者能深入浅出地讲解。

    有8位网友表示赞同!

喜欢梅西

智能指针在Qt中的应用真的很妙,但感觉代码复杂度增加了。

    有18位网友表示赞同!

拉扯

智能指针在Qt中的安全性确实很有优势,但有时候管理起来也相当头疼。

    有12位网友表示赞同!

軨倾词

Qt智能指针的学习让我对C++指针有了更深的理解,谢谢分享。

    有8位网友表示赞同!

优雅的叶子

看了教程,感觉Qt智能指针和C++的智能指针有点区别,能详细解释一下吗?

    有5位网友表示赞同!

志平

智能指针在Qt中的应用场景非常多,但有时候忘记怎么用,希望有更多实例。

    有17位网友表示赞同!

七夏i

学智能指针的时候,总是记不住各种构造函数,有没有什么好方法?

    有20位网友表示赞同!

有些人,只适合好奇~

Qt智能指针的内存管理真的很强大,但有时候觉得太复杂了。

    有10位网友表示赞同!

不要冷战i

智能指针在Qt中的应用让我对编程有了新的认识,感谢作者分享。

    有8位网友表示赞同!

々爱被冰凝固ゝ

Qt智能指针的学习让我对C++有了更深的兴趣,希望有更多深入的内容。

    有15位网友表示赞同!

我要变勇敢℅℅

智能指针在Qt中的应用让我意识到内存管理的重要性,谢谢作者的提醒。

    有6位网友表示赞同!

嘲笑!

学智能指针的过程中,发现Qt的文档不是很完善,有没有推荐的学习资源?

    有12位网友表示赞同!

青袂婉约

Qt智能指针的学习让我对C++指针的理解更加清晰,但感觉还是有点乱。

    有20位网友表示赞同!

昂贵的背影

智能指针在Qt中的应用让我对编程有了新的认识,希望有更多实战案例。

    有18位网友表示赞同!

娇眉恨

学智能指针的时候,发现Qt的智能指针和C++的智能指针有一些不同,能否详细说明一下?

    有11位网友表示赞同!

初阳

Qt智能指针的学习让我对编程有了更深的理解,但感觉还是有很多疑惑。

    有16位网友表示赞同!

抓不住i

智能指针在Qt中的应用让我对编程有了新的认识,希望有更多关于Qt智能指针的讨论。

    有14位网友表示赞同!

浅巷°

学Qt智能指针的过程中,感觉代码写起来更简洁了,但有时候还是会忘记怎么用。

    有9位网友表示赞同!

标签: