From 5d6888028afd4f59f9afcb5bed995d4d16395dee Mon Sep 17 00:00:00 2001 From: Awin Huang Date: Thu, 9 Jun 2022 14:50:27 +0800 Subject: [PATCH] vault backup: 2022-06-09 14:50:27 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Affected files: .obsidian/workspace 02. PARA/03. Resources(資源)/C++17/rvalue.md 02. PARA/03. Resources(資源)/C++17/智慧指標.md --- .obsidian/workspace | 12 +++--- .../03. Resources(資源)/C++17/rvalue.md | 37 +++++++++++-------- .../03. Resources(資源)/C++17/智慧指標.md | 2 +- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/.obsidian/workspace b/.obsidian/workspace index fb2e6ea..f52c700 100644 --- a/.obsidian/workspace +++ b/.obsidian/workspace @@ -10,7 +10,7 @@ "state": { "type": "markdown", "state": { - "file": "02. PARA/03. Resources(資源)/C++17/智慧指標.md", + "file": "02. PARA/03. Resources(資源)/C++17/rvalue.md", "mode": "source", "source": true } @@ -23,7 +23,7 @@ "state": { "type": "outline", "state": { - "file": "02. PARA/03. Resources(資源)/C++17/智慧指標.md" + "file": "02. PARA/03. Resources(資源)/C++17/rvalue.md" } } } @@ -81,7 +81,7 @@ "state": { "type": "backlink", "state": { - "file": "02. PARA/03. Resources(資源)/C++17/智慧指標.md", + "file": "02. PARA/03. Resources(資源)/C++17/rvalue.md", "collapseAll": true, "extraContext": true, "sortOrder": "alphabetical", @@ -125,15 +125,15 @@ }, "active": "94f0e8a81af6c9e2", "lastOpenFiles": [ - "02. PARA/03. Resources(資源)/C++17/智慧指標.md", "02. PARA/03. Resources(資源)/C++17/rvalue.md", + "02. PARA/03. Resources(資源)/C++17/move operator.md", + "02. PARA/03. Resources(資源)/C++17/智慧指標.md", "00. TOP/01. TODO.md", "02. PARA/03. Resources(資源)/git/submodule.md", "02. PARA/03. Resources(資源)/git.md", "02. PARA/01. Project(專案)/008. Sentinel.md", "02. PARA/03. Resources(資源)/C++17/lvalue.md", "02. PARA/03. Resources(資源)/FFMPEG/01. Setup.md", - "02. PARA/03. Resources(資源)/FFMPEG/00. Introduction.md", - "02. PARA/03. Resources(資源)/FFMpeg.md" + "02. PARA/03. Resources(資源)/FFMPEG/00. Introduction.md" ] } \ No newline at end of file diff --git a/02. PARA/03. Resources(資源)/C++17/rvalue.md b/02. PARA/03. Resources(資源)/C++17/rvalue.md index 0143ee7..5dc02c6 100644 --- a/02. PARA/03. Resources(資源)/C++17/rvalue.md +++ b/02. PARA/03. Resources(資源)/C++17/rvalue.md @@ -17,8 +17,8 @@ int b = 5; int& c = a + b; ``` -因為`a+b`是一個rvalue(臨時的值,沒辦法取址),所以無法參考。 -但是可以用`&&`來參考rvalue。例如: +因為`a+b`是一個 rvalue(臨時的值,沒辦法取址),所以無法參考。 +但是可以用`&&`來參考 rvalue。例如: ```cpp int a = 10; int b = 5; @@ -33,10 +33,10 @@ int r = a + b; int& c = r; ``` -了解rvalue reference之後,就可以實作類別的 move constructor 跟move assignment operator。這可以減少複製的成本。 +了解 rvalue reference 之後,就可以實作類別的 move constructor 跟 move assignment operator。這可以減少複製的成本。 ## Move constructor -假設我們有一個class叫BigBuffer,定義如下: +假設我們有一個 class 叫 BigBuffer,定義如下: ```cpp class BigBuffer { public: @@ -72,7 +72,7 @@ private: }; ``` -這個class的特色就是每一次使用都會佔用100MB的記憶體空間,想像下面的程式的動作: +這個 class 的特色就是每一次使用都會佔用100MB的記憶體空間,想像下面的程式的動作: ```cpp BigBuffer buf1; // Do something with buf1 @@ -87,7 +87,7 @@ BigBuffer copy constructor, copy 104857600Bytes // copy buf1 to buf2 ... ``` -這會先產生buf1,然後把buf1 copy給buf2。如果我們想要省下copy的成本,這時候 Move constructor 就可以派上用場了。 +這會先產生 buf1,然後把 buf1 copy 給 buf2。如果我們想要省下 copy 的成本,這時候 Move constructor 就可以派上用場了。 幫 BigBuffer 加一個 Move constructor: ```cpp class BigBuffer { @@ -106,9 +106,9 @@ public: }; ``` -這個 move constructor 的參數就是一個 rvalue reference,我們把來源的 bufferSize 跟 buffer指標「移到」我們這邊,而不是完整的複製一份。在轉移之後呢,當然也要把來源清空,讓轉移更加明確。 +這個 move constructor 的參數就是一個 rvalue reference,我們把來源的 bufferSize 跟 buffer 指標「移到」我們這邊,而不是完整的複製一份。在轉移之後呢,當然也要把來源清空,讓轉移更加明確。 -有了 Move assignment operator 之後,在執行一次原本的程式,你會發現訊息......沒有變,還是一樣呼叫 copy constructor 來複製了100MB的buffer,這時我們需要明確的告訴 compiler 我們要「移動」物件,而不是複製它,把原本的程式改為: +有了 Move assignment operator 之後,在執行一次原本的程式,你會發現訊息......沒有變,還是一樣呼叫 copy constructor 來複製了100MB 的 buffer,這時我們需要明確的告訴 compiler 我們要「移動」物件,而不是複製它,把原本的程式改為: ```cpp BigBuffer buf1; // Do something with buf1 @@ -123,7 +123,7 @@ BigBuffer move constructor // move buf1 to buf2, buf1 has nullptr now ... ``` -另外一個情形也可以受益於此,假如我們有個function會產生 BigBuffer,如下: +另外一個情形也可以受益於此,假如我們有個 function 會產生 `BigBuffer`,如下: ```cpp BigBuffer BigBufferCreator() { std::cout << "BigBufferCreator: Create a BigBuffer!\n"; @@ -136,7 +136,7 @@ BigBuffer BigBufferCreator() { BigBuffer b = BigBufferCreator(); // copy tempb to b ``` -在沒有Move constructor的情況下,上面的程式會先產生一個 tempb,然後複製給 b,訊息: +在沒有 Move constructor 的情況下,上面的程式會先產生一個 `tempb`,然後複製給 `b`,訊息: ``` BigBufferCreator: Create a BigBuffer! BigBuffer constructor @@ -145,7 +145,7 @@ BigBuffer copy constructor, copy 104857600Bytes // Copy 100MB! ... ``` -在有Move constructor的情況下,訊息就變成: +在有 Move constructor 的情況下,訊息就變成: ``` BigBufferCreator: Create a BigBuffer! BigBuffer constructor @@ -155,10 +155,10 @@ BigBuffer destructor BigBuffer destructor ``` -因為 `BigBufferCreator()` 產生的就是一個 BigBuffer rvalue,所以 compiler會使用 move constructor(`BigBuffer(BigBuffer&& src)`) 而不是 copy constructor。 +因為 `BigBufferCreator()` 產生的就是一個 `BigBuffer` rvalue,所以 compiler 會使用 move constructor(`BigBuffer(BigBuffer&& src)`) 而不是 copy constructor。 ## Move assignment operator(`=`) -Move assignment operator 的行為跟 move constructor 是一樣的,幫 BigBuffer 加入 move assignment operator: +Move assignment operator 的行為跟 move constructor 是一樣的,幫 `BigBuffer` 加入 move assignment operator: ```cpp class BigBuffer { public: @@ -196,8 +196,15 @@ BigBuffer b1, b2; b2 = std::move(b1); ``` -這樣就可以了。 +這樣就可以了。訊息: +``` +BigBuffer constructor +BigBuffer constructor +BigBuffer move operator // Use MOVE! +``` ## 參考 - [Value categories - cppreference.com](https://en.cppreference.com/w/cpp/language/value_category) -- [rvalue 參考](https://openhome.cc/Gossip/CppGossip/RvalueReference.html) \ No newline at end of file +- [rvalue 參考](https://openhome.cc/Gossip/CppGossip/RvalueReference.html) +- [Move constructors - cppreference.com](https://en.cppreference.com/w/cpp/language/move_constructor) +- [Move assignment operator - cppreference.com](https://en.cppreference.com/w/cpp/language/move_assignment) \ No newline at end of file diff --git a/02. PARA/03. Resources(資源)/C++17/智慧指標.md b/02. PARA/03. Resources(資源)/C++17/智慧指標.md index b1b59b6..d74fd00 100644 --- a/02. PARA/03. Resources(資源)/C++17/智慧指標.md +++ b/02. PARA/03. Resources(資源)/C++17/智慧指標.md @@ -68,7 +68,7 @@ auto ptr1 = std::make_unique(5); auto anotherPtr = std::move(ptr1); ``` -ptr1原本所管理的指標會轉移給 anotherPtr, +ptr1原本所管理的指標會轉移給 anotherPtr,ptr1 會變成 nullptr。 ## shared_ptr 建立一個 `shared_ptr` 是使用[`std::make_shared()`](https://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared):