From fa039f46411e6fb7d7ab3e69b31480cd91dae41e Mon Sep 17 00:00:00 2001 From: Awin Huang Date: Thu, 9 Jun 2022 14:10:26 +0800 Subject: [PATCH] vault backup: 2022-06-09 14:10:26 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Affected files: 02. PARA/03. Resources(資源)/C++17/rvalue.md --- .../03. Resources(資源)/C++17/rvalue.md | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/02. PARA/03. Resources(資源)/C++17/rvalue.md b/02. PARA/03. Resources(資源)/C++17/rvalue.md index 7088a41..341acb3 100644 --- a/02. PARA/03. Resources(資源)/C++17/rvalue.md +++ b/02. PARA/03. Resources(資源)/C++17/rvalue.md @@ -80,10 +80,47 @@ BigBuffer buf1; BigBuffer buf2 = buf1; ``` +執行訊息: +``` +BigBuffer constructor +BigBuffer copy constructor, copy 104857600Bytes +BigBuffer destructor +BigBuffer destructor +``` + 這會先產生buf1,然後把buf1 copy給buf2。如果我們想要省下copy的成本,這時候 Move assignment operator(就是 `=`)就可以派上用場了。 -幫 +幫 BigBuffer 加一個 Move assignment operator: +```cpp +class BigBuffer { +public: + ... + + BigBuffer& operator=(BigBuffer&& src) noexcept { + std::cout << "BigBuffer move operator\n"; + bufferSize = src.bufferSize; + buffer = std::move(src.buffer); + + src.buffer.reset(); + src.bufferSize = 0; + return *this; + } + ... +``` +這個 Move assignment operator 的參數就是一個 rvalue reference,我們把來源的 bufferSize 跟 buffer指標「移到」我們這邊,而不是完整的複製一份。在轉移之後呢,當然也要把來源清空,讓轉移更加明確。 +有了 Move assignment operator 之後,在執行一次原本的程式,你會發現訊息......沒有變,還是一樣呼叫 copy assignment operator 來複製了100MB的buffer,這時我們需要明確的告訴 compiler 我們要「移動」物件,而不是複製它,把原本的程式改為: +```cpp +BigBuffer buf1; +// Do something with buf1 +// Assign to buf2 +BigBuffer buf2 = std::move(buf1); +``` + +我們用 `std::move()` 來「移動」物件,這時輸出變成 +``` + +``` ## 參考 - [Value categories - cppreference.com](https://en.cppreference.com/w/cpp/language/value_category)