C++智能指针简明教程

顺便在此记录学习C++智能指针的一些重点和遗忘点。

首先需包含头文件 <memory>,并且智能指针命名空间在std中。

C++智能指针主要有三种:(1)shared_ptr / (2)unique_ptr / (3)weak_ptr

shared_ptr 最常用,没有什么限制;

unique_ptr 指分配的对象被一个指针所独占;

weak_ptr 是一种不控制对象生命周期的一种指针(不修改对象的引用计数)。

必须要注意的是,指针本身是栈空间里的,但指向的内容如果是通过动态内存分配的,则指向的内容是在堆中的。例如:

// 这里sp本身在栈中,指向的这个“10”的int空间在堆中。
shared_ptr<int> sp = make_shared<int>(10);// make_shared是较安全的智能指针初始化方法

shared_ptr通过对象的引用计数来自动控制动态分配的资源销毁,故不需要手动调用delete,调试时可用use_count()函数获取当前对象引用计数的值,所谓引用计数,就是针对某对象,总共有多少指针指向它。

shared_ptr<int> sp = make_shared<int>(1);
cout << sp.use_count() << endl;    // 此时打印1

shared_ptr<int> sp2 = sp;    // 此时sp2和sp指向同个对象,因此该对象的引用计数变为2
cout << sp.use_count() << endl;    // 此时打印2

shared_ptr两种初始化方法(直接初始化、make_shared):

// 直接调用new int()
shared_ptr<int> sp1(new int());   
// 调用make_shared,隐式调用int的默认构造函数 
shared_ptr<int> sp2 = make_shared<int>();    
// 调用make_shared,隐式调用参数为1的int构造函数
shared_ptr<int> sp3 = make_shared<int>(1);
// 调用make_shared,调用参数为"hello"的string构造函数  
shared_ptr<string> sp4 = make_shared<string>("hello");    

unique_ptr也有两种初始化方法,和shared_ptr类似,不过make_unique方法是C++14中才有的:

unique_ptr<int> up(new int());
unique_ptr<int> up1(new int(1));
unique_ptr<int> up2 = make_unique<int>();

使用shared_ptr或unique_ptr方法和 裸指针 一样,直接解引用即可,使用weak_ptr则需要先调用lock()返回一个shared_ptr类型指针,然后再使用:

shared_ptr<int> sp(new int());
weak_ptr<int> wp = sp;
cout << *(wp.lock()) << endl;    // wp.lock()返回shared_ptr类型

解释下weak_ptr为什么不控制对象的生命周期:当有个新的weak_ptr指向某对象时,并不会给该对象的引用计数加1,也就是说weak_ptr不会改变对象的引用计数,因此不会影响到对象的销毁。但是这样一来,就有种特殊情况:对象的引用计数已经是0了(代表已经释放),这时调用了weak_ptr读取或者操作该对象,程序会出现未定义的行为,此时应用以下代码:

weak_ptr<int> wp;    // 声明一个weak_ptr
{
    shared_ptr<int> sp = make_shared<int>(1);
    wp = sp;
}    // 退出该代码块时,shared_ptr指向的对象会释放,即wp指向的对象已释放了
// cout << *(wp.lock()) << endl;    // 这里报错,因为此时对象已过期,程序出现未定义行为
// 应该用下面的代码读取,expired代表对象已过期
if (!wp.expired()) {
    cout << *(wp.lock()) << endl;
}

weak_ptr常被用来避免循环引用导致的内存泄漏问题循环引用的详细问题可参考:【C++】weak_ptr弱引用智能指针详解_Yngz_Miao的博客-CSDN博客

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值