【C++笔记】智能指针(shared_ptr和weak_ptr)

C++中,动态内存的管理是通过newdelete一对运算符进行管理的。在代码编辑过程中,正确的释放内存空间往往复杂而困难。因此,为了更加安全的管理内存,C++11添加了智能指针。
想要使用智能指针,要先包含头文件< memory >

一,shared_ptr类

智能指针也是模板,因此在创建一个智能指针的时候要提供指针指向的类型

shared_ptr<int> p1;
shared_ptr<string>p2;
make_shared函数

在分配动态内存时,最安全的方法就是调用make_shared()函数,这个函数可以在动态内存中分配一个对象进行初始化并返回指向此对象的shared_ptr

shared_ptr<int> p3=make_shared<int>(1234);

在日常使用中,我们也可以使用auto类型的对象来保存make_shared()的结果

auto p4=make_share<string>("Hello World");
其他初始化方法

除了make_shared函数对shared_ptr对象进行初始化以外,还可以使用构造函数和拷贝构造函数对其进行初始化。

//调用构造函数进行初始化
shared_ptr<int>p4(new int(222));
//调用拷贝构造进行初始化
shared_ptr<int>p5(p4);

在使用构造函数初始化指针时要注意,智能指针的构造函数是使用explicit进行修饰的,因此不接受隐式转换

shared_ptr<int> p6=new int(1024);//会报错
shared_ptr内存管理

每个shared_ptr都会记录当前有多少个shared_ptr指向同一块内存,通过引用计数记录,使用use_count()方法可以获取计数器的数值。
当进行拷贝构造的时候,计数器会递增,当shared_ptr被销毁的时候,计数器会递减,当计数器为0时,就会释放所管理的对象。

auto p=make_shared<int>(111);	//当前计数器为1
auto q(p);	//计数器递增为2

使用reset()方法可以将当前共享指针的计数器清零并重置指针

shared_ptr<int>p7=make_shared(new int(123));
p7.reset();

不要混合使用普通指针和智能指针

void func(shared_ptr<int> ptr)
{
	/*代码段*/
}

int* x=new int(1024);//使用普通指针
func(x);	//合法,但是内存会被释放
int y=*x;	//报错,x指向的地址被释放

同理,在使用get()方法时要注意不要让它管理的指针被释放

shared_ptr<int>p(new int(1024));
int *q=p.get();//使用q时要注意如果p被释放,q也会悬空

二,weak_ptr类

weak_ptr是一种不控制所指向对象生存期的智能指针,它指向一个shared_ptr管理的对象。使用weak_ptr绑定到一个shared_ptr对象不会改变其引用计数,如果最后一个shared_ptr销毁,对象就会释放。

auto p=make_shared<int>(2);
weak_ptr<int>wp(p);//使用shared_ptr对weak_ptr进行初始化

由于对象有可能不存在,所以不能使用weak_ptr直接访问对象,而是要通过lock()方法才能访问

if(shared_ptr<int>np=wp.lock())//如果np不为空则条件成立
{
	//if中,np和p共享对象
}

其他用法

//观察对象的引用计数
np.use_count();
//观测指向对象是否被释放
np.expired();
//重置弱指针指向的对象
np.reset();
std::enable_shared_from_this
class CLA{
public:
    CLA(){
        std::cout << " CLA() is called" << std::endl;
    }
    ~CLA(){
        std::cout << "~CLA() is called" << std::endl;
    }

    std::shared_ptr<CAL> GetSharedObject(){
        return std::shared_ptr<CLA>(this);
    }
};

int main()
{
    std::shared_ptr<CLA> p(new CLA());
    std::shared_ptr<CLA> q = p->GetSharedObject();

    std::cout << p.use_count() << std::endl;
    std::cout << q.use_count() << std::endl;

    return 0;
}

使用shared_ptr管理this时,会出现多次调用析构函数而报错的现象。因此才要用到enable_shared_from_this,其内部是一个weak_ptr,不会影响指向对象的计数器,对象的构造和析构能正常调用

class CLA::public std::enable_shared_from_this<CLA> 
{
public:
    CLA(){
        std::cout << " CLA() is called" << std::endl;
    }
    ~CLA(){
        std::cout << "~CLA() is called" << std::endl;
    }

    std::shared_ptr<CAL> GetSharedObject(){
        return shared_from_this();
    }
};
  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值