智能指针
當你看到一個 int* ptr 在你的 c++ code 中使用,用完後要不要去 delete 它 ? 如果要,請問是使用 delete [] ptr or delete ptr ? 若後面的 code 有做 delete , 則 重複 delete 會造成 crush. 如果不要,而後面沒有 code 做 delete ,則造成 memory leak。 上述的困境,你一定遇過.., 而 smart pointer 就是來解決這樣的問題! (太棒了)
在 C++ 中,智能指针(smart pointers)提供了一種安全和自動化的資源管理方式。 C++11 引入了幾種不同類型的智能指针,其中包括 std::unique_ptr、std::shared_ptr 和 std::weak_ptr。每種智能指针都有其特定的使用情景和優點。
下面是這三種智能指针的使用時機及範例。
std::unique_ptr
std::unique_ptr 是一種獨占所有權的智能指针,確保某一時間只有一個指针擁有該資源。這樣可以防止資源泄漏和重複釋放資源。
使用時機:
- 當你希望某個對象有且只有一個所有者時。
- 用於實現 RAII(Resource Acquisition Is Initialization)模式。
- 避免指针的拷貝和共享。
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
#include <iostream>
#include <memory>
class Resource {
public:
Resource() { std::cout << "Resource acquired : "<< this << "\n"; }
~Resource() { std::cout << "Resource destroyed : "<< this <<"\n"; }
void sayHello() const { std::cout << "Hello, Resource from : " << this <<"\n"; }
};
int main() {
std::cout << "~Enter scope" << std::endl;
{
std::unique_ptr<Resource> res1(new Resource());
res1->sayHello();
// Transfer ownership
std::unique_ptr<Resource> res2 = std::move(res1);
if (!res1) {
std::cout << "res1 is null\n";
}
res2->sayHello();
// Resource will be automatically destroyed when res2 goes out of scope
}
std::cout << "~Leave scope" << std::endl;
std::cout << "------------" << std::endl;
std::cout << "~Enter scope" << std::endl;
{
int size = 3;
std::unique_ptr<Resource[]> res1 = std::make_unique<Resource[]>(size);
for (size_t i = 0; i < size; i++)
{
res1[i].sayHello();
}
// Transfer ownership
std::unique_ptr<Resource[]> res2 = std::move(res1);
if (!res1) {
std::cout << "res1 is null\n";
}
}
std::cout << "~Leave scope" << std::endl;
return 0;
}
當離開 scope 時,自動釋放資源
c++11 make_unique 支援創建動態數組
1
std::make_unique<Resource[]>(3);
std::shared_ptr
std::shared_ptr 是一種共享所有權的智能指针,允許多個指针指向同一個資源。當最後一個指向該資源的指针被銷毀時,資源會被自動釋放。
使用時機:
- 當你需要多個所有者共享同一個資源時。
- 當資源的生命週期需要在多個對象或函數之間共享時。
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
#include <iostream>
#include <memory>
class Resource {
public:
Resource() { std::cout << "Resource acquired : " << this << "\n"; }
~Resource() { std::cout << "Resource destroyed : " << this << "\n"; }
void sayHello() const { std::cout << "Hello, Resource from : " << this << "\n"; }
};
int main() {
std::shared_ptr<Resource> res1 = std::make_shared<Resource>();
std::cout << "res1.use_count : " << res1.use_count() << std::endl;
std::cout << "~Enter scope" << std::endl;
{
std::shared_ptr<Resource> res2 = res1;
res2->sayHello();
std::cout << "res1.use_count : " << res1.use_count() << std::endl;
std::cout << "res2.use_count : " << res2.use_count() << std::endl;
std::cout << "res2 goes out of scope\n";
}
std::cout << "~Leave scope" << std::endl;
std::cout << "res1.use_count : " << res1.use_count() << std::endl;
res1->sayHello();
std::cout << "res1 goes out of scope\n";
// Resource will be automatically destroyed when res1 goes out of scope
return 0;
}
use_count() 可以看到資源被多少 share pointer 持有。
res2 離開 scope 時,釋放對資源的持有權。
在 c++11 時,make_shared 還不支援創建動態數組
建動態數組會得到以下錯誤
1
std::shared_ptr<Resource[]> res1 = std::make_shared<Resource[]>(3);



