智能指针是C++11引入的,用于自动管理内存的对象。它们帮助开发者避免内存泄漏和其他与动态内存分配相关的问题。推荐使用标准库中的智能指针,因为它们提供了更好的内存管理功能。以下是几种常用的智能指针及其用法:
1. std::unique_ptr
std::unique_ptr
代表独占所有权的智能指针,意味着在任何给定时间,只有一个std::unique_ptr
可以指向特定对象。当std::unique_ptr
超出作用域时,它所指向的对象会被自动销毁。
用法示例:
#include <memory>
#include <iostream>
class MyClass {
public:
int value;
MyClass(int v) : value(v) {}
};
int main() {
std::unique_ptr<MyClass> myPtr = std::make_unique<MyClass>(10);
std::cout << myPtr->value << std::endl; // 输出 10
// 尝试将myPtr赋值给另一个unique_ptr
// std::unique_ptr<MyClass> anotherPtr = myPtr; // 这会编译错误
// 移动语义,转移所有权
std::unique_ptr<MyClass> anotherPtr = std::move(myPtr);
std::cout << anotherPtr->value << std::endl; // 输出 10
// myPtr不再有效,不应再使用
return 0;
}
2. std::shared_ptr
std::shared_ptr
允许多个智能指针共享对同一对象的所有权。对象的生命周期会持续到没有std::shared_ptr
指向它为止。
用法示例:
#include <memory>
#include <iostream>
int main() {
std::shared_ptr<MyClass> myPtr1 = std::make_shared<MyClass>(10);
std::shared_ptr<MyClass> myPtr2 = myPtr1; // 共享所有权
std::cout << myPtr1.use_count() << std::endl; // 输出 2
std::cout << myPtr2.use_count() << std::endl; // 输出 2
// 当myPtr1和myPtr2超出作用域时,对象被销毁
return 0;
}
3. std::weak_ptr
std::weak_ptr
是一种不控制对象生命周期的智能指针,它持有一个std::shared_ptr
的弱引用。std::weak_ptr
通常与std::shared_ptr
一起使用,以解决循环引用的问题。
用法示例:
#include <memory>
#include <iostream>
int main() {
std::shared_ptr<MyClass> myPtr1 = std::make_shared<MyClass>(10);
std::weak_ptr<MyClass> myWeakPtr = myPtr1;
// 检查weak_ptr是否有效
if (auto lockedPtr = myWeakPtr.lock()) {
std::cout << lockedPtr->value << std::endl; // 输出 10
}
// 当myPtr1超出作用域时,weak_ptr将不再有效
return 0;
}
智能指针的注意事项:
- 所有权转移:使用
std::move
可以将std::unique_ptr
的所有权从一个指针转移到另一个指针。 - 内存管理:智能指针会自动管理内存,当最后一个指向特定对象的智能指针被销毁时,对象也会被销毁。
- 异常安全:智能指针的设计是异常安全的,即使在构造或赋值过程中发生异常,也不会导致资源泄漏。
- 循环引用:使用
std::shared_ptr
时,要注意循环引用问题,这可能导致内存泄漏。std::weak_ptr
可以用来解决这个问题。