C++智能指针
1. 智能指针的作用
在C++操作堆内存非常频繁 ,堆内存的申请和释放需要程序员手动清理。虽然手动管理可以提高程序运行的效率,但整体操作起来比较频繁。使用普通指针容易造成堆内存的泄露(原因是忘记释放了),而二次释放又会引发其他问题, 因此C++11引入了智能指针的概念方便程序员更好的管理堆内存。
理解智能指针的三个层次:
- 智能指针利用了一种叫RAII(资源获取即初始化)的技术对普通的指针进行了封装。使得智能指针实质是一个对象,实际操作时的行为表现却像是一个指针。
- 智能指针的作用是为了防止调用delete时忘记释放内存以及程序异常时忘记释放内存,以及多次释放内存时造成程序崩溃。
- 智能指针的作用是把值语意转换成引用语意。
在Java中:
Animal a = new Animal();
Animal b = a; // 这里b是a的一个引用
但在C++中,却会生成两个对象
Animal a = new Animal();
Animal b = a;
2. 智能指针的使用
智能指针在C++11以后提供,包含在头文件<menmory>
文件中,其中包括了shared_ptr、unique_ptr、weak_ptr
2.1 shared_ptr的使用
shared_ptr多个指针指向相同的对象。shared_ptr使用引用计数法,每一次使用shared_ptr都会使计数器自加1,每一次析构时又会使计数器自减1,减为0时自动使得引用指向的堆内存释放。引用计数在线程上是安全的,但对象的读取需要加锁。
- 初始化
智能指针是一个模版类,可以指定类型。传入指针可以通过构造函数初始化,也可以使用make_shared初始化。不能直接将指针复制给智能指针,因为一个是类,一个是指针。shared_ptr<int> p1 = new int(1024); // 这个写法是错误的
- 拷贝和赋值。
拷贝使得对象的引用计数增加1,赋值使得原对象引用计数减1,当计数为0时,自动释放内存。后来指向的对象引用计数加1,指向后来的对象。 - 通过get()函数获得原始指针。
- 注意不要用一个原始指针同时赋值多个shared_ptr容易造成二次释放同一内存。
- 因为采用了计数器的方式,容易造成循环引用。导致内存得不到释放。