vault backup: 2022-06-06 11:34:20
Affected files: 02. PARA/03. Resources(資源)/C++17/智慧指標.md
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
unique_ptr與shared_ptr都是智慧指標,箱對於原本的raw pointer,智慧指標使用起來更方便,也不用擔心delete的問題。
|
unique_ptr與shared_ptr都是智慧指標,箱對於原本的raw pointer,智慧指標使用起來更方便,也不用擔心delete的問題。
|
||||||
|
|
||||||
## unique_ptr
|
## unique_ptr
|
||||||
`unique_ptr`的特點是,它保證在一個時間內,只會有一個指標的擁有者,也就是這個指標不能被複製跟移動,當`unique_ptr`離開它的scope時候,它所擁有的pointer也隨之被delete。這讓你不用擔心memory leak的問題。
|
[`unique_ptr`](https://en.cppreference.com/w/cpp/memory/unique_ptr)的特點是,它保證在一個時間內,只會有一個指標的擁有者,也就是這個指標不能被複製跟移動,當`unique_ptr`離開它的scope時候,它所擁有的指標也隨之被delete。這讓你不用擔心memory leak的問題。
|
||||||
原本分配記憶體的方法,假設我們有一個class叫`BigBuffer`:
|
假設我們有一個class叫`BigBuffer`,原本分配記憶體的方法:
|
||||||
```cpp
|
```cpp
|
||||||
BigBuffer* bigBuf = new BigBuffer(bufferSize);
|
BigBuffer* bigBuf = new BigBuffer(bufferSize);
|
||||||
// Use buffer here
|
// Use buffer here
|
||||||
@@ -16,7 +16,7 @@ auto bigBuf = std::make_unique<BigBuffer>(bufferSize);
|
|||||||
// bigBuf will be released when exiting scope
|
// bigBuf will be released when exiting scope
|
||||||
```
|
```
|
||||||
|
|
||||||
我們統一用`std::make_unique<>`這個template function來建立`unique_ptr`,角括號`<>`裡面要帶入你要建立的型別,後面的括號`()`就是型別的constructor,使用起來跟`new`是一樣的。
|
我們統一用[`std::make_unique<>`](https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique)這個template function來建立`unique_ptr`,角括號`<>`裡面要帶入你要建立的型別,後面的括號`()`就是型別的constructor,使用起來跟`new`是一樣的。
|
||||||
因為`std::make_unique<>`裡面已經有表明型別了,所以變數就用`auto`就可以了,不用再寫一次型別。
|
因為`std::make_unique<>`裡面已經有表明型別了,所以變數就用`auto`就可以了,不用再寫一次型別。
|
||||||
|
|
||||||
一旦`unique_ptr`建立之後,使用起來就跟一般指標沒有兩樣,都是用`->`來操作:`bigBuf->setXXX()` or `bigBuf->getXXX()`。
|
一旦`unique_ptr`建立之後,使用起來就跟一般指標沒有兩樣,都是用`->`來操作:`bigBuf->setXXX()` or `bigBuf->getXXX()`。
|
||||||
@@ -40,7 +40,7 @@ auto intArray = std::make_unique<int[]>(1024);
|
|||||||
intArray[5] = 555;
|
intArray[5] = 555;
|
||||||
```
|
```
|
||||||
|
|
||||||
不過對於陣列的操作現在更建議使用`std::array`。
|
不過對於陣列的操作更建議使用`std::array`。
|
||||||
|
|
||||||
如果有什麼特殊原因讓你決定不再讓`unique_ptr`來幫你管理指標,可以用`release()`來讓出指標:
|
如果有什麼特殊原因讓你決定不再讓`unique_ptr`來幫你管理指標,可以用`release()`來讓出指標:
|
||||||
```cpp
|
```cpp
|
||||||
@@ -60,7 +60,7 @@ std::unique_ptr<int> ptr2 = ptr1; // Error
|
|||||||
|
|
||||||
|
|
||||||
## shared_ptr
|
## shared_ptr
|
||||||
建立一個`shared_ptr`是使用`std::make_shared()`:
|
建立一個[`shared_ptr`](https://en.cppreference.com/w/cpp/memory/shared_ptr)是使用[`std::make_shared()`](https://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared):
|
||||||
```cpp
|
```cpp
|
||||||
auto myBuf = std::make_shared<BigBuffer>(bufferSize);
|
auto myBuf = std::make_shared<BigBuffer>(bufferSize);
|
||||||
```
|
```
|
||||||
@@ -78,7 +78,7 @@ myBuf->setZero(startAddr, endAddr);
|
|||||||
bufCopy->setOne(startAddr, endAddr);
|
bufCopy->setOne(startAddr, endAddr);
|
||||||
```
|
```
|
||||||
|
|
||||||
`shared_ptr`內部有一個參考記數(reference count)來紀錄它所擁有的指標已經分享給幾個變數了,只要有變數離開了他的scope,參考記數就會減少,反之,要是像上面那樣有人複製的指標,參考記數就會增加,參考記數歸0的時候,指標就會被釋放。
|
`shared_ptr`內部有一個參考記數(reference count)來紀錄它所擁有的指標已經分享給幾個變數了,只要有變數離開了他的scope,參考記數就會減少,反之,要是像上面那樣有人複製指標,參考記數就會增加,參考記數歸0的時候,指標就會被釋放。
|
||||||
|
|
||||||
有了`shared_ptr`我們就不必擔心delete的責任問題:
|
有了`shared_ptr`我們就不必擔心delete的責任問題:
|
||||||
```cpp
|
```cpp
|
||||||
@@ -96,4 +96,4 @@ int main() {
|
|||||||
|
|
||||||
`shared_ptr`有一個問題是可以會「循環參考」(cyclic references),也就是share_ptr A指向另一個share_ptr B,然後share_ptr B又指向share_ptr A,這造成參考記數(reference count)不會減少而永遠無法釋出指標。這個是需要注意的。
|
`shared_ptr`有一個問題是可以會「循環參考」(cyclic references),也就是share_ptr A指向另一個share_ptr B,然後share_ptr B又指向share_ptr A,這造成參考記數(reference count)不會減少而永遠無法釋出指標。這個是需要注意的。
|
||||||
|
|
||||||
但是`shared_ptr`還是讓記憶體的ㄈ
|
但是`shared_ptr`還是讓記憶體的管理問題減少很多,應該用`shared_ptr`來代替`new` & `delete`。
|
||||||
|
|||||||
Reference in New Issue
Block a user