vault backup: 2022-06-09 14:30:26
Affected files: 02. PARA/03. Resources(資源)/C++17/rvalue.md
This commit is contained in:
@@ -33,7 +33,7 @@ int r = a + b;
|
|||||||
int& c = r;
|
int& c = r;
|
||||||
```
|
```
|
||||||
|
|
||||||
了解rvalue reference之後,就可以實作類別的 move constructor 跟move assignment operator。
|
了解rvalue reference之後,就可以實作類別的 move constructor 跟move assignment operator。這可以減少複製的成本。
|
||||||
|
|
||||||
## Move constructor
|
## Move constructor
|
||||||
假設我們有一個class叫BigBuffer,定義如下:
|
假設我們有一個class叫BigBuffer,定義如下:
|
||||||
@@ -103,6 +103,7 @@ public:
|
|||||||
src.bufferSize = 0;
|
src.bufferSize = 0;
|
||||||
}
|
}
|
||||||
...
|
...
|
||||||
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
這個 move constructor 的參數就是一個 rvalue reference,我們把來源的 bufferSize 跟 buffer指標「移到」我們這邊,而不是完整的複製一份。在轉移之後呢,當然也要把來源清空,讓轉移更加明確。
|
這個 move constructor 的參數就是一個 rvalue reference,我們把來源的 bufferSize 跟 buffer指標「移到」我們這邊,而不是完整的複製一份。在轉移之後呢,當然也要把來源清空,讓轉移更加明確。
|
||||||
@@ -140,15 +141,57 @@ BigBuffer b = BigBufferCreator(); // copy tempb to b
|
|||||||
BigBufferCreator: Create a BigBuffer!
|
BigBufferCreator: Create a BigBuffer!
|
||||||
BigBuffer constructor
|
BigBuffer constructor
|
||||||
BigBufferCreator: return
|
BigBufferCreator: return
|
||||||
BigBuffer copy constructor, copy 104857600Bytes
|
BigBuffer copy constructor, copy 104857600Bytes // Copy 100MB!
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
在有Move constructor的情況下,訊息就變成:
|
在有Move constructor的情況下,訊息就變成:
|
||||||
```
|
```
|
||||||
|
BigBufferCreator: Create a BigBuffer!
|
||||||
|
BigBuffer constructor
|
||||||
|
BigBufferCreator: return
|
||||||
|
BigBuffer move constructor // Use MOVE!
|
||||||
|
BigBuffer destructor
|
||||||
|
BigBuffer destructor
|
||||||
```
|
```
|
||||||
|
|
||||||
|
因為 `BigBufferCreator()` 產生的就是一個 BigBuffer rvalue,所以 compiler會使用 move constructor(`BigBuffer(BigBuffer&& src)`) 而不是 copy constructor。
|
||||||
|
|
||||||
|
## Move assignment operator(`=`)
|
||||||
|
Move assignment operator 的行為跟 move constructor 是一樣的,幫 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;
|
||||||
|
}
|
||||||
|
...
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
測試程式:
|
||||||
|
```cpp
|
||||||
|
BigBuffer b1, b2;
|
||||||
|
b2 = b1;
|
||||||
|
```
|
||||||
|
|
||||||
|
訊息:
|
||||||
|
```
|
||||||
|
BigBuffer constructor
|
||||||
|
BigBuffer constructor
|
||||||
|
BigBuffer copy operator, copy 104857600Bytes
|
||||||
|
```
|
||||||
|
|
||||||
|
還是使用 copy operator
|
||||||
|
|
||||||
## 參考
|
## 參考
|
||||||
- [Value categories - cppreference.com](https://en.cppreference.com/w/cpp/language/value_category)
|
- [Value categories - cppreference.com](https://en.cppreference.com/w/cpp/language/value_category)
|
||||||
- [rvalue 參考](https://openhome.cc/Gossip/CppGossip/RvalueReference.html)
|
- [rvalue 參考](https://openhome.cc/Gossip/CppGossip/RvalueReference.html)
|
||||||
Reference in New Issue
Block a user