智能指针是什么?

智能指针对已有C++指针的封装,方便内存管理,一个有三种智能指针,但是使用中主要分为两种场景:
1.unique_ptr 的独占所有权特性,无法复制只能移动move()
2.shared_ptr 和weak_ptr共同使用.
shared_ptr的引用计数机制,多个指针共享同一资源。
weak_ptr 的弱引用特性,不增加引用计数,通过 lock () 安全访问对象

基础使用?

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
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <iostream>
#include <memory>
#include <string>
#include <windows.h>


using namespace std;

// 前向声明
class A;
class B;
class C;

// 声明全局弱引用指针用于观察
weak_ptr<A> global_weak_a;
weak_ptr<B> global_weak_b;
weak_ptr<C> global_weak_c;

// 类定义
class B {
public:
shared_ptr<A> aPtr;
~B() {
cout << "B被销毁" << endl;
}
};

class A {
public:
shared_ptr<B> bPtr;
shared_ptr<C> cPtr;
~A() {
cout << "A被销毁" << endl;
}
};


class C {
public:
weak_ptr<A> aPtr; // 使用shared_ptr会导致循环引用

~C() {
cout << "C被销毁" << endl;
}
};

//=====================================================================
//Unique_ptr智能指针示例
void UniquePtrExample(){
//创建一个智能指针,管理一个动态分配的字符串对象
std::unique_ptr<std::string> strPtr = std::make_unique<std::string>("Hello, Smart Pointer!");
std::unique_ptr<std::string> strPtr2 = std::move(strPtr); //将strPtr的所有权转移给strPtr2
//std::unique_ptr<string> c = strPtr; // 语法错误:unique_ptr不能被复制,只能移动
//检查strPtr是否为空
if (strPtr == nullptr) {
std::cout << "strPtr is now empty after ownership transfer." << std::endl;
} else {
std::cout << "strPtr is not empty: " << *strPtr << std::endl;
}
std::cout<<"strPtr2 is not empty: " << *strPtr2 << std::endl;


}
//shared_ptr智能指针示例
void circularReferenceExample() {
std::cout << "---进入函数作用域---" << std::endl;
auto a = std::make_shared<A>();
auto b = std::make_shared<B>();

std::cout << "创建后 - A的引用计数: " << a.use_count() << std::endl;
std::cout << "创建后 - C的引用计数: " << b.use_count() << std::endl;

a->bPtr = b; // B的引用计数加1
b->aPtr = a; // A的引用计数加1

std::cout << "设置互相引用后 - A的引用计数: " << a.use_count() << std::endl;
std::cout << "设置互相引用后 - B的引用计数: " << b.use_count() << std::endl;
std::cout << "---函数作用域即将结束---" << std::endl;

//函数结束后
//局部变量a被销毁,a的引用计数: 2->1
//局部变量b被销毁,b的引用计数: 2->1

}

//shared_ptr和weak_ptr智能指针示例
void break_circularReferenceExample() {

// 创建两个对象并互相引用
auto a = make_shared<A>();
cout << "A的引用计数: " << a.use_count() << endl;

auto c = make_shared<C>();
cout << "C的引用计数: " << c.use_count() << endl;

global_weak_a = a;
global_weak_c = c;

a->cPtr = c;
cout << "设置 a->bPtr 后,c的引用计数: " << c.use_count() << endl;

c->aPtr = a;
cout << "设置 c->aPtr 后,A的引用计数: " << a.use_count() << endl;

cout << "\n作用域结束前:" << endl;
cout << "A的引用计数: " << a.use_count() << endl;
cout << "C的引用计数: " << c.use_count() << endl;

cout << "\n作用域结束后" << endl;
// 此时由于循环引用,对象不会被销毁
//函数结束后
//局部变量a被销毁,a的引用计数: 1->0,
//致使指向c的指针被销毁,c的引用计数减一 2—>1,局部变量c被销毁,c的引用计数减一: 1->0
}

//=====================================================================
int main() {
// 设置控制台编码为 UTF-8
SetConsoleOutputCP(65001);

cout << "开始测试循环引用..." << endl;
//UniquePtrExample();
//circularReferenceExample();
//shared_ptr和weak_ptr智能指针示例
break_circularReferenceExample();
cout << "\n程序结束" << endl;

// 最后再次检查对象状态
auto final_a = global_weak_a.lock();
auto final_b = global_weak_b.lock();
auto final_c = global_weak_c.lock();
cout << "\n检查对象状态..." << endl;

cout << "\n程序结束时的状态:" << endl;
cout << "A对象: " << (final_a ? "仍然存在" : "已被销毁") << endl;
cout << "B对象: " << (final_b ? "仍然存在" : "已被销毁") << endl;
cout << "C对象: " << (final_c ? "仍然存在" : "已被销毁") << endl;

system("pause");
return 0;
}

游戏应用

1.场景管理父子关系,容器与元素之间的关系

1
2
3
4
5
6
7
8
9
10
class Parent;
class Child;

class Parent {
shared_ptr<Child> child; // 强引用
};

class Child {
weak_ptr<Parent> parent; // 弱引用,防止循环引用
};