智能指针
C++ 中的智能指针(Smart Pointers)是用于自动管理动态分配内存的指针。它们与普通指针(raw pointers)不同,智能指针自动管理内存的生命周期,以避免内存泄漏和悬挂指针等问题。C++ 标准库提供了几种常用的智能指针:
std::unique_ptr
std::shared_ptr
std::weak_ptr
std::unique_ptr
特点
- 独占所有权:每个
unique_ptr
对象独占其管理的资源,不能共享所有权。 - 不可复制:
unique_ptr
不允许复制,但可以移动。 - 自动释放:当
unique_ptr
离开作用域时,自动释放所管理的资源。
示例
#include <iostream>
#include <memory>
class MyClass {
public:
MyClass() { std::cout << "MyClass Constructor" << std::endl; }
~MyClass() { std::cout << "MyClass Destructor" << std::endl; }
};
int main() {
std::unique_ptr<MyClass> ptr1(new MyClass()); // 创建一个 unique_ptr
// std::unique_ptr<MyClass> ptr2 = ptr1; // 错误:unique_ptr 不可复制
std::unique_ptr<MyClass> ptr2 = std::move(ptr1); // 移动所有权
return 0; // 自动调用 MyClass 的析构函数
}
std::shared_ptr
特点
- 共享所有权:多个
shared_ptr
可以共享同一个资源,使用引用计数来管理资源的生命周期。 - 自动释放:当最后一个
shared_ptr
离开作用域时,自动释放所管理的资源。
示例
#include <iostream>
#include <memory>
class MyClass {
public:
MyClass() { std::cout << "MyClass Constructor" << std::endl; }
~MyClass() { std::cout << "MyClass Destructor" << std::endl; }
};
int main() {
std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>(); // 创建一个 shared_ptr
{
std::shared_ptr<MyClass> ptr2 = ptr1; // 共享所有权
std::cout << "ptr2's use count: " << ptr2.use_count() << std::endl; // 输出 2
} // ptr2 离开作用域,不销毁资源
std::cout << "ptr1's use count: " << ptr1.use_count() << std::endl; // 输出 1
return 0; // 自动调用 MyClass 的析构函数
}
std::weak_ptr
特点
- 弱引用:
weak_ptr
不增加资源的引用计数,主要用于打破shared_ptr
之间的循环引用。 - 配合
shared_ptr
使用:weak_ptr
不能独立管理资源,必须从一个shared_ptr
创建。
示例
#include <iostream>
#include <memory>
class MyClass {
public:
MyClass() { std::cout << "MyClass Constructor" << std::endl; }
~MyClass() { std::cout << "MyClass Destructor" << std::endl; }
};
int main() {
std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();
std::weak_ptr<MyClass> weakPtr = ptr1; // 创建一个 weak_ptr
std::cout << "ptr1's use count: " << ptr1.use_count() << std::endl; // 输出 1
if (auto ptr2 = weakPtr.lock()) { // 尝试锁定 weak_ptr 得到 shared_ptr
std::cout << "Lock succeeded. ptr1's use count: " << ptr1.use_count() << std::endl; // 输出 2
} else {
std::cout << "Lock failed." << std::endl;
}
return 0; // 自动调用 MyClass 的析构函数
}
智能指针与普通指针的区别
-
内存管理:
- 智能指针:自动管理内存的生命周期,当不再使用时自动释放资源,避免内存泄漏。
- 普通指针:需要手动管理内存的分配和释放,容易导致内存泄漏和悬挂指针。
-
所有权:
- 智能指针:可以明确所有权关系,
unique_ptr
独占所有权,shared_ptr
共享所有权,weak_ptr
弱引用不持有所有权。 - 普通指针:没有所有权概念,多个指针可以指向同一块内存,没有自动管理机制。
- 智能指针:可以明确所有权关系,
-
安全性:
- 智能指针:提供安全的资源管理,防止悬挂指针和重复释放。
- 普通指针:容易导致悬挂指针、内存泄漏和重复释放。
-
性能:
- 智能指针:引入了少量的性能开销(如引用计数的维护)。
- 普通指针:直接操作内存,没有额外开销,但需要更小心的管理。
总结
智能指针在 C++ 中提供了一种安全、方便的内存管理机制,帮助开发者避免常见的内存管理错误。根据具体需求,选择合适的智能指针类型可以有效提高代码的安全性和可维护性。