目录
相较于前面手动挡控制内存的开辟和释放,C++这里有一个智能指针,可以在作用域实现内存的开辟和释放,实现了自动挡功能。
C++ 中的 智能指针 是一种封装原始指针的类,用于自动管理动态分配的内存,确保在不再需要时自动释放内存,从而减少内存泄漏和悬空指针等问题。智能指针的主要类型包括 std::unique_ptr
、std::shared_ptr
和 std::weak_ptr
,它们分别提供了不同的内存管理策略。
1. std::unique_ptr
- 特性:独占所有权。一个
std::unique_ptr
只能指向一个对象,并且不能被复制,但可以转移所有权。 - 用法:通常用于表示独占的资源,自动释放资源。
创建:
unique_ptr<Entity> e0 = make_unique<Entity>();
#include <iostream>
#include <memory> // 需要包含这个头文件
class Entity {
public:
Entity() { std::cout << "Entity created\n"; }
~Entity() { std::cout << "Entity destroyed\n"; }
};
int main() {
std::unique_ptr<Entity> ptr1(new Entity()); // 创建 unique_ptr
// std::unique_ptr<Entity> ptr2 = ptr1; // 错误,不能复制
std::unique_ptr<Entity> ptr2 = std::move(ptr1); // 转移所有权
// ptr1 现在为空,ptr2 拥有 Entity 对象
if (!ptr1) {
std::cout << "ptr1 is null\n";
}
return 0; // ptr2 超出作用域,Entity 会被自动销毁
}
2. std::shared_ptr
- 特性:共享所有权。多个
std::shared_ptr
可以指向同一个对象,引用计数管理对象的生命周期,当计数结束的时候说明这个内存会被释放。 - 用法:适用于多个所有者共享同一资源的场景。
创建:
shared_ptr<Entity> e1 = make_shared<Entity>();
使用示例:
#include <iostream>
#include <memory>
class Entity {
public:
Entity() { std::cout << "Entity created\n"; }
~Entity() { std::cout << "Entity destroyed\n"; }
};
int main() {
std::shared_ptr<Entity> ptr1(new Entity()); // 创建 shared_ptr
{
std::shared_ptr<Entity> ptr2 = ptr1; // ptr1 和 ptr2 共享同一个 Entity
std::cout << "Use count: " << ptr1.use_count() << std::endl; // 计数为 2
} // ptr2 超出作用域,计数减少
std::cout << "Use count: " << ptr1.use_count() << std::endl; // 计数为 1
return 0; // ptr1 超出作用域,Entity 会被自动销毁
}
作用域问题:
执行完里层的作用域这个内存并不会被释放,当整个作用域执行完成后这个共享指针指向的内存才会被释放。
int main() {
{
shared_ptr<Entity> e_ptr;
{
shared_ptr<Entity> e1 = make_shared<Entity>();
e_ptr= e1;
}
}
cin.get();
}
3. std::weak_ptr
- 特性:不影响引用计数的智能指针。用于解决
std::shared_ptr
的循环引用问题。 - 用法:通常与
std::shared_ptr
配合使用,以避免内存泄漏。