Files
Obsidian-Main/02. PARA/03. Resources(資源)/C++17/智慧指標.md
Awin Huang a779779c22 vault backup: 2022-06-06 10:54:20
Affected files:
02. PARA/03. Resources(資源)/C++17/智慧指標.md
2022-06-06 10:54:20 +08:00

53 lines
2.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
unique_ptr與shared_ptr都是智慧指標箱對於原本的raw pointer智慧指標使用起來更方便也不用擔心delete的問題。
## unique_ptr
unique_ptr的特點是它保證在一個時間內只會有一個指標的擁有者也就是這個指標不能被複製跟移動當unique_ptr離開它的scope時候它所擁有的pointer也隨之被delete。這讓你不用擔心memory leak的問題。
原本分配記憶體的方法假設我們有一個class叫BigBuffer
```cpp
BigBuffer* bigBuf = new BigBuffer(bufferSize);
// Use buffer here
delete bigBuf;
```
用unique_ptr
```cpp
auto bigBuf = std::make_unique<BigBuffer>(bufferSize);
// Use buffer here
// bigBuf will be released when exiting scope
```
我們統一用`std::make_unique<>`這個template function來建立unique_ptr角括號<>裡面要帶入你要建立的型別,後面的括號()就是型別的constructor使用起來跟new是一樣的。
因為`std::make_unique<>`裡面已經有表明型別了所以變數就用auto就可以了不用再寫一次型別。
一旦unique_ptr建立之後使用起來就跟一般指標沒有兩樣都是用`->`來操作:`bigBuf->setXXX()` or `bigBuf->getXXX()`
但是別忘記unique_ptr本身還是一個local variable所以我們可以用`.`來操作unique_ptr例如我們可以用`.reset()`重新配一個指標:
```cpp
bigBuf.reset(std::make_unique<BigBuffer>(bufferSizeLarger));
```
這時候舊指標會自動delete然後指向新的指標如果記憶體分配有成功的話或者指向nullptr記憶體分配失敗
如果單純想要釋放指標那就單純的reset就好。
```cpp
bigBuf.reset(); // Now I'm nullptr
```
如果要分配陣列的話:
```cpp
auto intArray = std::make_unique<int[]>(1024);
```
使用方式也是一樣的:
```cpp
intArray[5] = 555;
```
不過對於陣列的操作現在更建議使用std::array。
如果有什麼特殊原因讓你決定不再讓unique_ptr蘭幫你管理指標可以用`release`來讓出指標:
```cpp
auto intArray = std::make_unique<int[]>(1024);
int* intArrayRaw =
```
## shared_ptr