TIP💡
关于智能指针中的基础知识可以看一下 对象生存周期
智能指针 unique_ptr
unique_ptr 是作用域指针,超过作用域时会进行销毁,在 对象生存周期中提及的作用域指针其实就是 unique_ptr。
Unique_ptr 指针从字面意思理解就是指该指针是独一无二的,而事实上也确实如此。unique_ptr指针不能复制,因为复制之后两者指向的是同一个内存空间,当其中一个指针关闭时,会销毁指向的内存空间,导致两者指向已回收的内存。
#include<memory>
class Entity
{
public:
Entity()
{
std::cout << "创建对象" << std::endl;
}
~Entity()
{
std::cout << "销毁对象" << std::endl;
}
void print() {}
};
int main()
{
{
std::unique_ptr<Entity> entity(new Entity());
//使用make_unique创建unique_ptr会更加安全
//可避免构造函数异常时变成没有引用的悬空指针
std::unique_ptr<Entity> entity = std::make_unique<Entity>();
//下列做法是错误的
std::unique_ptr<Entity> e0 = entity;
entity->print();
}
}智能指针 shared_ptr
Shared_ptr 相比 unique_ptr,可以从字面意思上看出 shared_ptr 可以共享(复制)。Shared_ptr 通过引用计数来决定是否销毁,如果没有对象引用该指针,即引用计数为 0 时,指针将会自动销毁。
#include<memory>
class Entity
{
public:
Entity()
{
std::cout << "创建对象" << std::endl;
}
~Entity()
{
std::cout << "销毁对象" << std::endl;
}
void print() {}
};
int main()
{
//例子1
{
std::shared_ptr<Entity> entity(new Entity());
//shared_ptr需要分配额外内存给控制块,记录引用计数
//使用make_shared可以更高效地分配内存
std::shared_ptr<Entity> entity = std::make_shared<Entity>();
//shared_ptr可以进行复制
std::shared_ptr<Entity> e0 = entity;
}
//例子2
{
std::shared_ptr<Entity> e0;
{
//此时引用计数变为1
std::shared_ptr<Entity> shared_entity = std::make_shared<Entity>();
//引用计数变为2
e0 = shared_entity;
}//离开shared_entity的作用域,引用计数变为1
}//离开e0的作用域,引用计数变为0,entity对象销毁
{
//weak_ptr不会增加引用计数
std::weak_ptr<Entity> e0;
{
//此时引用计数变为1
std::shared_ptr<Entity> shared_entity = std::make_shared<Entity>();
//引用计数仍然为1
e0 = shared_entity;
}
//离开shared_entity的作用域,引用计数变为0,销毁entity对象
//e0指向一个无效的Entity对象
}
}Weak_ptr 指针与 shared_ptr 唯一的区别在于不增加引用计数,对于对象的有效性和所属权并不关心的时候,可以使用 weak_ptr 指针,weak_ptr 可以指向存活的对象,但是不能保活。
Comment
智能指针可以有效地自动化管理内存,如果在代码中不需要显式地调用 delete 管理内存,那么使用智能指针是一个不错的选择。其中 shared_ptr 相比 unique_ptr ,有额外的引用计数,因此有着更高的系统开销,所以在使用智能指针时应优先考虑 unique_ptr,如果存在对象间共享的需求,再考虑 shared_ptr。