一,智能指针
1.智能指针简介
智能指针是用法和行为类似于指针的类对象。
智能指针的底层对原始指针做了一定的封装。
智能指针除了像指针一样可以存储变量的地址,还提供了其他功能,比如可以管理动态内存分配,对引用进行计数等。
当智能指针所指向的变量离开了作用域或被重置时,智能指针会自动释放该变量所占用的堆内存资源。
至于为什么要引入智能指针,可以参考下面这段代码:
void func_1()
{
Sample* obj_one = new Sample();
if(something_wrong())
throw exception();
delete obj_one;
}
每次调用该函数的时候,都需要在堆中申请一段内存,然后在函数的最后释放该内存。但是当函数运行期间出现异常的时候,delete将不被执行,此时申请到的内存得不到释放,会发生内存泄露。智能指针由于是类对象,该类对象可以在析构的时候自动释放智能指针所指向的内存。因此,如果此时使用智能指针代替原始指针,可以不用手动调用"delete/delete []",智能指针指向的堆内存会自动被释放。
上述代码可以改写为:
void func_2()
{
auto obj_two = make_unique<Sample>();
if(something_wrong())
throw exception();
}
当unique_ptr实例离开作用域时(代码执行到了函数末尾,或者函数抛出异常),就会在其析构函数中自动释放obj_two对象所占有的内存资源。
标准库中提供了相应的类模板,它们可以将任何数据类型封装成智能指针,使用它们时,需要引入<memory>头文件。
智能指针常用的类模板有:
std::unique_ptr<T>
std::shared_ptr<T>
std::weak_ptr<T>
由上述的类模板可以生成三种类型的智能指针实例。这三种智能指针实例的区别在于,管理原始指针的方式不一样。
shared_ptr允许多个指针指向同一个变量。
unique_ptr则独占所指向的变量。
weak_ptr则指向shared_ptr所管理的变量。
2.智能指针的基础用法
1.智能指针的初始化
智能指针是基于类模板生成的,因此,要初始化一个智能指针,就必须声明指针所指向的数据类型,不然智能指针里面包含的原始指针是个空指针。
初始化方式一,在智能指针构造函数中new一个新对象。
struct C{
int a;
int b;
};
std::shared_ptr<C> p1(new C);
std::unique_ptr<int> p2(new int(40));
初始化方式二,采用make_shared函数(C