更多文章欢迎访问 程序员小非 博客
很多人怕写C/C++ 程序就是因为指针,因为指针给了程序员高度的自由,同样也赋予了高度的责任,稍有不慎就导致内存泄漏。其实写C++ 可以完全不用指针,尤其C++ 11对智能指针作了进一步的升级,在不需要使用任何裸指针的前提下也可以写出高效的C++ 程序。C++ 11中定义了unique_ptr
、shared_ptr
与weak_ptr
三种智能指针(smart pointer),都包含在<memory>
头文件中。智能指针可以对动态分配的资源进行管理,保证任何情况下,已构造的对象最终会销毁,即它的析构函数最终会被调用。
unique_ptr
如名字所示,unique_ptr
是个独占指针,C++ 11之前就已经存在,unique_ptr
所指的内存为自己独有,某个时刻只能有一个unique_ptr
指向一个给定的对象,不支持拷贝和赋值。下面以代码样例来说明unique_ptr
的用法,各种情况都在代码注释给出。
#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include <map>
void test()
{
std::unique_ptr<int> up1(new int(11)); // 无法复制的unique_ptr
// unique_ptr<int> up2 = up1; // err, 不能通过编译
std::cout << *up1 << std::endl; // 11
std::unique_ptr<int> up3 = std::move(up1); // 现在p3是数据的唯一的unique_ptr
std::cout << *up3 << std::endl; // 11
// std::cout << *up1 << std::endl; // err, 运行时错误,空指针
up3.reset(); // 显式释放内存
up1.reset(); // 不会导致运行时错误
// std::cout << *up3 << std::endl; // err, 运行时错误,空指针
std::unique_ptr<int> up4(new int(22)); // 无法复制的unique_ptr
up4.reset(new int(44)); // "绑定"动态对象
std::cout << *up4 << std::endl; // 44
up4 = nullptr; // 显式销毁所指对象,同时智能指针变为空指针。与up4.reset()等价
std::unique_ptr<int> up5(new int(55));
int *p = up5.release(); // 只是释放控制权,不会释放内存
std::cout << *p << std::endl;
// cout << *up5 << endl; // err, 运行时错误,不再拥有内存
delete p; // 释放堆区资源
return;
}
shared_ptr
shared_ptr
允许多个该智能指针共享“拥有”同一堆分配对象的内存,这通过引用计数(reference counting)实现,会记录有多少个shared_ptr共同指向一个对象,一旦最后一个这样的指针被销毁,也就是一旦某个对象的引用计数变为0,这个对象会被自动删除。支持复制和赋值操作。
#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include <map>
void test()
{
std::shared_ptr<int> sp1(new int(22));
std::shared_ptr<int> sp