智能指针
new在堆上分配内存,需要delete来释放内存。智能指针是实现这一过程自动化的一种方式,当你用new的时候不需要调用delete,很多时候用智能指针甚至不需要调用new。智能指针本质上是原始指针的包装,当你创建智能指针的时候,它会调用new并分配内存,然后在某一时刻这些内存会自动释放。
unique_ptr
unique_ptr是作用域指针,当超出作用域时它会被销毁然后delete。(低开销,甚至无开销)
#include <iostream>
#include <string>
#define LOG(X) std::cout << X << std::endl
class Entity
{
public:
Entity()
{
LOG("Create Entity");
}
~Entity()
{
LOG("Destoryed Entity");
}
};
int main()
{
{
//std::unique_ptr<Entity> entity(new Entity());
std::unique_ptr<Entity> entity = std::make_unique<Entity>();//因为异常安全,所有用make_unique不用new
}
}
注:不能复制,因为复制之后这些unique_ptr中的某一死掉之后,它们都会“死”
shared_ptr
shared_ptr的工作方式是通过引用计数,可以追踪指针有多少引用,一旦引用数为零它就被删除了。
shared_ptr需要分配一块内存叫做控制块,用来储存引用计数。如果先new一个对象,然后再把她(不要在意为什么是女字旁的她)传递给shared_ptr构造函数,它必须做两次内存分配,先做一次new的分配,然后再做一次shared_ptr的控制内存块的分配。如果用make_shared可以把它们组合在一起,这样更有效率。
#include <iostream>
#include <string>
#define LOG(X) std::cout << X << std::endl
class Entity
{
public:
Entity()
{
LOG("Create Entity");
}
~Entity()
{
LOG("Destoryed Entity");
}
};
int main()
{
{
std::shared_ptr<Entity> e0;
{
std::shared_ptr<Entity> sharedEntity = std::make_shared<Entity>();
e0 = sharedEntity;
}
}
std::cin.get();
}
这里引用数是2,当sharedEntity被销毁时并没有调用Entity类的析构函数,只有当e0被销毁时引用数变为1,才调用了析构函数。
weak_ptr
当把shared_ptr赋值给shared_ptr时会增加引用数,但把shared_ptr赋值给weak_ptr不会增加引用数。