智能指针
new在堆上分配内存,delete删除内存,智能指针是实现这一过程自动化的一种方式
unique_ptr
作用域指针,不能被复制,因为如果复制后,两个指针同时指向一个内存,如果其中一个死了,会释放那块内存,所以另一指针指向一段被释放的内存。
举例
#include <iostream>
class Entity
{
private:
int x;
public:
Entity()
{
std::cout << "create entity" << std::endl;
}
~Entity()
{
std::cout << "destroy entity" << std::endl;
}
void Print()
{}
};int main()
{
{
std::unique_ptr<Entity> entity(new Entity);
entity->Print();
}
std::cin.get();
}
也可以更改为以下代码,防止内存泄漏
#include <iostream>
class Entity
{
private:
int x;
public:
Entity()
{
std::cout << "create entity" << std::endl;
}
~Entity()
{
std::cout << "destroy entity" << std::endl;
}
void Print()
{}
};int main()
{
{
std::unique_ptr<Entity> entity = std::make_unique<Entity>();
entity->Print();
}
std::cin.get();
}
当作用煜结束后,entity会被自动摧毁
这也是最简单的智能指针,但不能复制和拷贝,如下,不能将entity复制给e0
#include <iostream>
class Entity
{
private:
int x;
public:
Entity()
{
std::cout << "create entity" << std::endl;
}
~Entity()
{
std::cout << "destroy entity" << std::endl;
}
void Print()
{}
};int main()
{
{
std::unique_ptr<Entity> entity = std::make_unique<Entity>();
std::unique_ptr<Entity> e0 = entity;
entity->Print();
}
std::cin.get();
}
会报错,如果我们需要复制,我们需要用到共享指针
shared_ptr
举例
通过shared_ptr可以实现复制
#include <iostream>
class Entity
{
private:
int x;
public:
Entity()
{
std::cout << "create entity" << std::endl;
}
~Entity()
{
std::cout << "destroy entity" << std::endl;
}
void Print()
{}
};int main()
{
{
std::shared_ptr<Entity>e0;
{
std::shared_ptr<Entity>entity = std::make_shared<Entity>();
e0 = entity;
}
}
std::cin.get();
}
当我们debug时,可以发现,std::shared_ptr<Entity>e0;没有分配内存给e0所以没用调用构造函数,std::shared_ptr<Entity>entity = std::make_shared<Entity>();时出现create entity,引用计数为1, e0 = entity;后引用计数为2,然后在}之后,entity被消灭,但并没有调用~Entity(),这是因为,e0还持有对Entity的引用,当第2个}后,e0也被消灭,此时引用计数减为0,没有对Entity类的引用,所以调用~Entity(),出现destroy entity
weak_ptr
不会增加引用计数,它不会让底层对象保持存活,通常和shared_ptr一起用
举例
当把上面代码中shared_ptr改成weak_ptr时,代码如下
#include <iostream>
class Entity
{
private:
int x;
public:
Entity()
{
std::cout << "create entity" << std::endl;
}
~Entity()
{
std::cout << "destroy entity" << std::endl;
}
void Print()
{}
};int main()
{
{
std::weak_ptr<Entity>e0;
{
std::shared_ptr<Entity>entity = std::make_shared<Entity>();
e0 = entity;
}
}
std::cin.get();
}
和之前不同,在std::shared_ptr<Entity>entity = std::make_shared<Entity>();时,调用构造函数,引用计数为1,e0 = entity;后引用计数不变,为1,在}后引用计数减为0,没有对Entity类的引用,调用~Entity(),出现destroy entity
总结
当要声明一个堆分配对象,并且不希望自己来清理,就应该使用智能指针,unique_ptr有更小的内存开销(单纯因为栈内存不够大时常用),如果需要在对象之间共享,用shared_ptr,

1049

被折叠的 条评论
为什么被折叠?



