std::auto_ptr<QLabel> label(new QLabel("Hello Dbzhang800!"));
智能指针 | 引入 | |
---|---|---|
QPointer | Qt Object 模型的特性(之一)注意:析构时不会delete它管理的资源 | |
QSharedPointer | 带引用计数 | Qt4.5 |
QWeakPointer | Qt4.5 | |
QScopedPointer | Qt4.6 | |
QScopedArrayPointer | QScopedPointer的派生类 | Qt4.6 |
QSharedDataPointer | 用来实现Qt的隐式共享(Implicit Sharing) | Qt4.0 |
QExplicitlySharedDataPointer | 显式共享 | Qt4.4 |
std::auto_ptr | ||
std::shared_ptr | std::tr1::shared_ptr | C++0x |
std::weak_ptr | std::tr1::weak_ptr | C++0x |
std::unique_ptr | boost::scoped_ptr | C++0x |
- QPointer (4.0) 已经过时,可以被QWeakPointer所替代,它不是线程安全的。
- QSharedDataPointer (4.0) – 提供对数据的COPY-ON-WRITE以及浅拷贝,提供对数据(而不是指向数据的指针)的线程安全的保护。(注:提供对数据的线程安全保护要结合QsharedData来完成),它是线程安全的。
- QSharedPointer (4.5) – 实现了引用计数的可共享资源的强类型指针,它是线程安全的。
- QWeakPointer (4.5) – 实现了引用计数的可共享资源的弱类型指针,它是线程安全的。
- QScopedPointer (4.6) – 实现了非引用计数的独享资源的强类型指针,它是线程安全的。
QSharedPointer有着与std::auto_ptr类似的特性,而最大的区别在于它不能转让所有权而auto_ptr可以。事实上,scoped_ptr永远不能被复制或被赋值!
std::auto_ptr
- 不能让多个auto_ptr 指向同一个对象!(auto_ptr被销毁时会自动删除它指向的对象,这样对象会被删除多次)
- 通过拷贝构造或赋值进行操作时,被拷贝的会自动变成NULL,复制所得的指针将获得资源的唯一所有权
- 智能指针不能指向数组(因为其实现中调用的是delete而非delete[])
- 智能指针不能作为容器类的元素。
在C++0x中,auto_ptr已经不建议使用,以后应该会被其他3个智能指针所取代。
QScopedPointer 与std::unique_ptr
它们概念上应该是是一样的。下面不再区分:
这是一个很类似auto_ptr的智能指针,它包装了new操作符在堆上分配的动态对象,能够保证动态创建的对象在任何时候都可以被正确地删除。但它的所有权更加严格,不能转让,一旦获取了对象的管理权,你就无法再从它那里取回来。
无论是QScopedPointer 还是 std::unique_ptr 都拥有一个很好的名字,它向代码的阅读者传递了明确的信息:这个智能指针只能在本作用域里使用,不希望被转让。因为它的拷贝构造和赋值操作都是私有的,这点我们可以对比QObject及其派生类的对象。
QSharedPointer 与 std::shared_ptr
QSharedPointer 与 std::shared_ptr 行为最接近原始指针,是最像指针的”智能指针”,应用范围比前面的提到的更广。
QSharedPointer 与 QScopedPointer 一样包装了new操作符在堆上分配的动态对象,但它实现的是引用计数型的智能指针 ,可以被自由地拷贝和赋值,在任意的地方共享它,当没有代码使用(引用计数为0)它时才删除被包装的动态分配的对象。shared_ptr也可以安全地放 到标准容器中,并弥补了std::auto_ptr 和 QScopedPointer 因为转移语义而不能把指针作为容器元素的缺陷。