智能指针(Smart Pointers)
# 智能指针(Smart Pointers)
Created: March 19, 2024 2:25 PM
在C++中,智能指针是一种实现了自动资源管理的类模板,它们封装了原始指针,并通过自动管理内存分配和释放来帮助防止内存泄露和悬挂指针问题。C++11标准引入了三种主要的智能指针:std::unique_ptr
、std::shared_ptr
和std::weak_ptr
。
# std::unique_ptr
**std::unique_ptr
是一种独占所有权的智能指针,意味着同一时间只能有一个std::unique_ptr
实例拥有对对象的所有权。当std::unique_ptr
**被销毁时(例如,离开作用域),它指向的对象也会被自动销毁。
# 示例:
#include <iostream>
#include <memory>class Example {
public:
Example() { std::cout << "Example created\n"; }
~Example() { std::cout << "Example destroyed\n"; }
};
int main() {
{
std::unique_ptr<Example> ptr = std::make_unique<Example>();
// 使用ptr->...
} // ptr离开作用域,指向的Example对象被自动销毁
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# std::shared_ptr
**std::shared_ptr
是一种共享所有权的智能指针,允许多个std::shared_ptr
实例共享对同一个对象的所有权。引用计数被用来跟踪有多少个std::shared_ptr
实例拥有同一个对象。当最后一个这样的std::shared_ptr
**被销毁时,对象会被自动删除。
# 示例:
#include <iostream>
#include <memory>class Example {
public:
Example() { std::cout << "Example created\n"; }
~Example() { std::cout << "Example destroyed\n"; }
};
int main() {
std::shared_ptr<Example> ptr1 = std::make_shared<Example>();
{
std::shared_ptr<Example> ptr2 = ptr1; // ptr1和ptr2共享对象
std::cout << "Inside the block\n";
} // ptr2被销毁,对象不会被删除,因为ptr1仍然存在
std::cout << "Outside the block\n";
} // ptr1被销毁,对象被删除
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# std::weak_ptr
**std::weak_ptr
是一种不控制对象生命周期的智能指针,它被设计用来解决std::shared_ptr
之间的循环引用问题。std::weak_ptr
持有对对象的弱引用,这意味着即使你有一个或多个std::weak_ptr
**指向一个对象,它也不会阻止对象被删除。
# 示例:
#include <iostream>
#include <memory>
class Example : public std::enable_shared_from_this<Example> {
public:
std::weak_ptr<Example> peer; // 弱引用,不控制生命周期
void greet() {
if (auto p = peer.lock()) { // 尝试获取一个std::shared_ptr
std::cout << "Hello from peer\n";
} else {
std::cout << "Peer is gone\n";
}
}
~Example() { std::cout << "Example destroyed\n"; }
};
int main() {
auto ptr1 = std::make_shared<Example>();
auto ptr2 = std::make_shared<Example>();
ptr1->peer = ptr2;
ptr2->peer = ptr1; // 创建了一个循环引用
ptr1->greet();
ptr2.reset(); // 释放ptr2指向的对象
ptr1->greet(); // 现在peer指向的对象已经被销毁了
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
这些智能指针通过自动管理内存,大大降低了内存泄露的风险,是现代C++编程中推荐使用的方式来处理动态分配的资源。
编辑 (opens new window)