智能指针使用

最近在复习C++的一些相关知识,正好把智能指针重新梳理一遍。


智能指针

作用

为什么需要智能指针?
	说白了就是为了更加“方便智能”的管理内存,当使用原始指针有时候会因为忘记释放内存,从而导致内存泄漏
。智能指针则可以帮我们释放new出来的内存。

1.auto_ptr

	auto_ptr 是通过由 new 表达式获得的对象,并在 auto_ptr 自身被销毁时删除该对象的智能指针。
它可用于为动态分配的对象提供异常安全、传递动态分配对象的所有权给函数和从函数返回动态分配的对象。
	复制 auto_ptr ,会复制指针并转移所有权给目标: auto_ptr 的复制构造和复制赋值都会修改其右侧参数,
而且“副本”不等于原值。因为这些不常见的复制语义,不可将 auto_ptr 置于标准容器中。
此用途及其他使用更适合用 std::unique_ptr 。 (C++11 起)

示例

#include <iostream>
#include <memory>
using namespace std;

class Test {
    int a;
public:
    Test() : a(0) {cout << "a = 0" << endl;}
    //explicit Test(int i) : a(i) {cout << "int";}
    Test(int i) : a(i) {cout << "a:"<< a << endl;}
    Test(short s) : a(s) {cout << "short";}
    Test &operator=(int n) {a = n; cout << "operator=";}

    ~Test()
    {
        cout << "析构" << endl;
    }
};



int main() {

    auto_ptr<Test> t(new Test(5));
    auto_ptr<Test> t1(new Test);
    //auto_ptr<int []> t2(new int[5]);  //不支持(2)
    unique_ptr<int []> t3(new int[5]);

    cout << t.get() << endl;
    cout << t1.get() << endl;
    t = t1;			//(1) ,建议不要这样使用
    cout << t.get() << endl;
    cout << t1.get() << endl;    

    return 0;
}
现在一般不使用auto_ptr<>,主要其存在诸多弊端:
1.复制或者赋值都会改变资源的所有权 ,见代码(1)
2.在STL容器中使用auto_ptr存在着重大风险,因为容器内的元素必须支持可复制和可赋值,原因可参考(1)
3.不支持对象数据内存管理,见(2)

所以,C++11用更严谨的unique_ptr 取代了auto_ptr。

unique_ptr

1.基于排他所有权模式:两个指针不能指向同一个资源
2.无法进行左值unique_ptr复制构造,也无法进行左值复制赋值操作,但允许临时右值赋值构造和赋值
3.保存指向某个对象的指针,当它本身离开作用域时会自动释放它指向的对象。
4.在容器中保存指针是安全的
    unique_ptr<Test> t(new Test(5));
    unique_ptr<Test> t1(new Test);
    cout << "---------------" << endl;
    //t = t1;   //不支持,两个指针不能指向同一资源
    //unique_ptr<Test> t2(t1);//不支持,可以理解为不能指向同一资源
    unique_ptr<Test> t3(move(t1));//允许,移动了所有权,将t1的所有权给了t3

shared_ptr

std::shared_ptr 是通过指针保持对象共享所有权的智能指针。多个 shared_ptr 对象可占有同一对象。
下列情况之一出现时销毁对象并解分配其内存:
1.最后剩下的占有对象的 shared_ptr 被销毁;
2.最后剩下的占有对象的 shared_ptr 被通过 operator= 或 reset() 赋值为另一指针。
这就是共享模式,他很好的解决了unique_ptr<>的缺点,使得多个指针能够指向同一个资源。
    shared_ptr<Test> t(new Test(5));
    shared_ptr<Test> t1(new Test());

    cout << t.use_count() << endl;	//引用计数
    cout << t.unique() << endl;//判断当前是否仅有一个指针进行管理
    cout << t1.use_count() << endl;
    t1 = t;
    cout << "t1 = t" << endl;
    cout << t1.use_count() << endl;	// t1 和 t两个指针进行管理
    cout << t.use_count() << endl;
    cout << t.unique() << endl;
    cout << "-------------------" << endl;

智能指针常用方法

1.reset
替换所管理的对象
(公开成员函数)

2.swap
交换所管理的对象
(公开成员函数)

3.get
返回存储的指针
(公开成员函数)

4.use_count
返回 shared_ptr 所指对象的引用计数
(公开成员函数)

5.unique
(C++20 前)
检查所管理对象是否仅由当前 shared_ptr 的实例管理

4和5为共享指针所有

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值