53 lines
2.1 KiB
Markdown
53 lines
2.1 KiB
Markdown
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 |