# 智能指针的实现原理是什么?
# 简要回答
基于RAII设计理念,通过对象的生命周期管理资源。
是通过类模板封装原始指针实现的,它利用 RAII(资源获取即初始化)机制,在对象生命周期结束时,自动释放资源,避免内存泄漏。
它本质上是一个包装类,重载了解引用操作符‘*’和 成员访问操作符 ->,让它像普通指针一样使用,但可以自动管理资源。
# 详细回答
C++智能指针是一种通过RAII(资源获取即初始化)技术来管理动态分配内存的类模版,其核心原理是将原始指针封装在对象内部,并在对象生命周期结束时自动释放内存,包括三类指针。
1.unique_ptr:独占所有权,禁止拷贝但允许移动,通过删除拷贝构造函数和赋值运算符,只保留移动语义,析构时释放所管理的内存。
2.shared_ptr: 共享所有权,通过引用计数管理内存使用一块额外的控制块存储引用计数和弱引用计数,每次拷贝时引用计数加1,析构时减1,计数为0时释放内存;
3.weak_ptr:弱引用,不控制生命周期,用于解决shared_ptr的循环引用计数与shared_ptr共享控制块,但不增加引用计数,通过lock()方法获取一个临时shared_ptr来访问对象。
# 代码示例
用 unique_ptr 创建一只Dog,它生命周期完全由某个函数独占;
用 shared_ptr 共享一只Dog的所有权,模拟多个对象共享资源;
用 weak_ptr 观察这只Dog是否还活着,避免循环引用或悬空指针
#include <iostream>
#include <memory>
class Dog {
public:
std::string name;
Dog(const std::string& name) : name(name) {
std::cout << "Dog " << name << " is created." << std::endl;
}
~Dog() {
std::cout << "Dog " << name << " is destroyed." << std::endl;
}
void bark() {
std::cout << name << " says: Woof!" << std::endl;
}
};
void useUniquePtr() {
std::unique_ptr<Dog> dog1 = std::make_unique<Dog>("UniqueDog");
dog1->bark();
// dog1 自动释放资源
}
void useSharedAndWeakPtr() {
std::shared_ptr<Dog> sharedDog = std::make_shared<Dog>("SharedDog");
std::cout << "Shared use_count: " << sharedDog.use_count() << std::endl;
// 创建一个 weak_ptr,观察 sharedDog
std::weak_ptr<Dog> weakDog = sharedDog;
{
// 另一个 shared_ptr 拷贝,引用计数 +1
std::shared_ptr<Dog> sharedDog2 = sharedDog;
std::cout << "Inside block, use_count: " << sharedDog.use_count() << std::endl;
} // sharedDog2 离开作用域,引用计数 -1
std::cout << "Outside block, use_count: " << sharedDog.use_count() << std::endl;
// 使用 weak_ptr 检测 shared_ptr 管理的对象是否还在
if (std::shared_ptr<Dog> lockedDog = weakDog.lock()) {
std::cout << "Dog is still alive, name: " << lockedDog->name << std::endl;
lockedDog->bark();
} else {
std::cout << "Dog has been destroyed." << std::endl;
}
// sharedDog 离开作用域后,Dog 被销毁
}
int main() {
std::cout << "=== unique_ptr 示例 ===" << std::endl;
useUniquePtr();
std::cout << "\n=== shared_ptr 和 weak_ptr 示例 ===" << std::endl;
useSharedAndWeakPtr();
std::cout << "\n=== 程序结束 ===" << std::endl;
return 0;
}
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# 知识拓展
std::make_shared 的优势
相比 new,它只申请一次内存,效率更高,缓存友好:
auto p = std::make_shared<MyClass>(); // 推荐
- 控制块
在 shared_ptr 和 weak_ptr 中,为了支持共享引用计数,C++标准库内部引入一个控制块(Control Block)
struct ControlBlock {
void* ptr; // 原始资源
std::atomic<int> shared_count; // shared_ptr 引用数
std::atomic<int> weak_count; // weak_ptr 引用数
};
2
3
4
5
shared_ptr 和 weak_ptr 都指向同一个控制块,当 shared_count 为 0 时释放资源;当两个计数都为 0 时释放控制块本身。
知识图解

评论
验证登录状态...