C++11中的智能指针

在C++11中,引入了智能指针。主要有:unique_ptr, shared_ptr, weak_ptr。
这3种指针组件就是采用了boost里的智能指针方案。很多有用过boost智能指针的朋友,很容易地就能发现它们之间的关间:

unique_ptr scoped_ptr 独占指针对象,并保证指针所指对象生命周期与其一致
shared_ptr shared_ptr 可共享指针对象,可以赋值给shared_ptr或weak_ptr。
指针所指对象在所有的相关联的shared_ptr生命周期结束时结束,是强引用。
weak_ptr weak_ptr 它不能决定所指对象的生命周期,引用所指对象时,需要lock()成shared_ptr才能使用。

C++11将boost里的这一套纳入了标准。

如下为示例代码:


//文件 test-1.cpp
#include <memory>
#include <iostream>

using namespace std;

int main()
{
    unique_ptr<int> up1(new int(11));
    unique_ptr<int> up2 = up1;   //! 编译时会出错 [1]

    cout << *up1 << endl;
    unique_ptr<int> up3 = move(up1);  //! [2]
    cout << *up3 << endl;
    if (up1)
        cout << *up1 << endl;

    up3.reset();  //! [3]
    up1.reset();

    shared_ptr<string> sp1(make_shared<string>("Hello"));
    shared_ptr<string> sp2 = sp1;
    cout << "*sp1:" << *sp1 << endl;
    cout << "*sp2:" << *sp2 << endl;
    sp1.reset();
    cout << "*sp2:" << *sp2 << endl;

    weak_ptr<string> wp = sp2; //! [4]
    cout << "*wp.lock():" << *wp.lock() << endl;
    sp2.reset();
    cout << "*wp.lock():" << *wp.lock() << endl;  //! 运行时会出错
    return 0;
}
//编译命令: g++ -std=c++11 test-1.cpp

[1]: unique_ptr 是禁止复制赋值的,始终保持一个 unique_ptr 管理一个对象。
[2]: unique_ptr 虽然不能赋值,但可以通过 move() 函数转移对象的所有权。一旦被 move() 了,原来的 up1 则不再有效了。
[3]: reset() 可以让 unique_ptr 提前释放指针。
[4]: 由 shared_ptr 构造一个 weak_ptr

shared_ptr 与 weak_ptr

如下面的示例:


shared_ptr<string> s1(new string);
shared_ptr<string> s2 = s1;
weak_ptr<string> w1 = s2;

在内存中:

s1, s2, w1 都指向一个 ptr_manage 的对象。
在该对象中有 shared_ref_count 与 weak_ref_count 两个域分别记录引用它的 shared_ptr 与 weak_ptr 的个数。这个很容易办到,只要在复制构造与赋值函数中对相当地引用值进行加1,在析构中减1即可。ptr_manage 中的 ptr 域存放真正的对象指针地址。

当 shared_ref_cnt 被减为0时,自动释放 ptr 指针所指向的对象。当 shared_ref_cnt 与 weak_ref_cnt 都变成0时,才释放 ptr_manage 对象。
如此以来,只要有相关联的 shared_ptr 存在,对象就存在。weak_ptr 不影响对象的生命周期。当用 weak_ptr 访问对象时,对象有可能已被释放了,要先 lock()

当执行:


s1.reset()

此时: 

shared_ref_cnt 由2减成了1。

再执行:


s2.reset()

此时:

shared_ref_cnt 已被减到0了,ptr 所对应的object已被释放,ptr 被清0。此时,ptr_manage 依旧保留。因为 w1 还需要引用它。

在最后,w1 也析构了的时候:

ptr_manage 中的 weak_ref_cnt 被减成0,最后连 ptr_manage 都释放了。

时间: 2024-09-10 17:10:34

C++11中的智能指针的相关文章

C++中auto_ptr智能指针的用法详解_C 语言

智能指针(auto_ptr) 这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限.本文总结的8个问题足以涵盖auto_ptr的大部分内容. auto_ptr是什么? auto_ptr 是C++标准库提供的类模板,auto_ptr对象通过初始化指向由new创建的动态内存,它是这块内存的拥有者,一块内存不能同时被分给两个拥有者.当auto_ptr对象生命周期结束时,其析构函数会将auto_ptr对象拥有

在Word 2007中使用智能指针功能

智能指针是Word中的一项编程功能,用户可以在Word2007中启用或取消智能指针功能,操作步骤如下所述: 第1步, 打开Word2007文档窗口,依次单击"Office按钮"→"Word选项"按钮,如图2012040307所示. 图2012040307 单击 "Word选项"按钮 第2步,打开"Word选项"对话框,切换到"高级"选项卡.在"编辑选项"区域选中或取消"使用智

在VC中使用智能指针操作Excel

最近的一个工程中,需要将数据导入Excel表格中,项目经理知道我以前没有接触过操作Excel的经验,于是给了一段小程序给我,让我参考着做. 这段程序是使用智能指针操作Excel,在网络上找了一个星期,居然没有一片关于智能指针操作Excel的文章,只有Automation技术,而且所有介绍Automation技术的文章都是大同小异,并且代码多,说明少.没有任何帮助,光有一堆代码,对于理解和使用没有太大的帮助.在这样一个艰苦的条件下,我决定利用手中仅有的工具:Microsoft Excel Visu

c++11-感觉C++11的智能指针也不太好 没有dynamic_cast

问题描述 感觉C++11的智能指针也不太好 没有dynamic_cast 解决方案 ""智能指针"",也就是对于一种过了气的的,没有垃圾回收的语言最后能做的一点小修小补了. 解决方案二: 其中B是A的基类 如果在一段用到基类的多态代码中 动态类型识别出派生类来 那也无法转换成派生类来用没有大神来指点一下么 解决方案三: C++11智能指针c++11 智能指针到C++11中的智能指针

c++11教程 智能指针讲解

如果在程序中使用new从堆(自由存储区)分配内存,等到不需要时, 应使用delete将其释放.c++引入了智能指针auto_ptr, 以帮助自动完成这个过程. c++11摒弃了auto_ptr,并新增了三种智能指针:unique_ptr, shared_ptr, weak_ptr. 一. auto_ptr, unique_ptr , shared_ptr 头文件:  #include <memory> 用法:auto_ptr<double>  A(new double);uniqu

C++中的auto_ptr智能指针的作用及使用方法详解_C 语言

智能指针(auto_ptr) 这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限.本文总结的8个问题足以涵盖auto_ptr的大部分内容.  auto_ptr是什么? auto_ptr 是C++标准库提供的类模板,auto_ptr对象通过初始化指向由new创建的动态内存,它是这块内存的拥有者,一块内存不能同时被分给两个拥有者.当auto_ptr对象生命周期结束时,其析构函数会将auto_ptr对象拥

引用内部函数绑定机制,R转义字符,C++引用,别名,模板元,宏,断言,C++多线程,C++智能指针

 1.引用内部函数绑定机制 #include<iostream> #include<functional>   usingnamespacestd; usingnamespacestd::placeholders;   //仿函数,创建一个函数指针,引用一个结构体内部或者一个类内部的共有函数 structMyStruct {    voidadd(inta)    {        cout <<a <<endl;    }    voidadd2(in

C++ 智能指针详解

来源:http://blog.csdn.net/xt_xiaotian/article/details/5714477 一个智能指针就是一个C++的对象, 这对象的行为像一个指针,但是它却可以在其不需要的时候自动删除.注意这个"其不需要的时候", 这可不是一个精确的定义.这个不需要的时候可以指好多方面:局部变量退出函数作用域.类的对象被析构--.所以boost定义了多个不同的智能指针来管理不同的场景. shared_ptr<T> 内部维护一个引用计数器来判断此指针是不是需要

指针辨析:悬垂指针、哑指针、野指针、智能指针

悬垂指针:   1:提出的原因: 请看下面的代码片段: int *p=NULL; void main() { int i=10;p=&i; cout<<"第一次:*p = "<<*p<<endl; cout<<"第二次:*p = "<<*p<<endl; } int *p=NULL; void fun() {int i=10;p=&i;} void main() { fun();