90 lines
2.2 KiB
Markdown
90 lines
2.2 KiB
Markdown
rvalue 是指:
|
||
- 等號右邊的值
|
||
- 臨時的值,例如運算的結果
|
||
- 無法被取址(address-of)的物件
|
||
|
||
## rvalue reference
|
||
一般的參考只能參考[[lvalue]],如下的程式是ok的:
|
||
```cpp
|
||
int a = 10;
|
||
int& b = a;
|
||
```
|
||
|
||
但是像這樣就不行了:
|
||
```cpp
|
||
int a = 10;
|
||
int b = 5;
|
||
int& c = a + b;
|
||
```
|
||
|
||
因為`a+b`是一個rvalue(臨時的值,沒辦法取址),所以無法參考。
|
||
但是可以用`&&`來參考rvalue。例如:
|
||
```cpp
|
||
int a = 10;
|
||
int b = 5;
|
||
int&& c = a + b; // c = 15
|
||
```
|
||
|
||
而不用這樣:
|
||
```cpp
|
||
int a = 10;
|
||
int b = 5;
|
||
int r = a + b;
|
||
int& c = r;
|
||
```
|
||
|
||
了解rvalue reference之後,就可以實作類別的 move constructor 跟move assignment operator。
|
||
|
||
## Move assignment operator
|
||
假設我們有一個class叫BigBuffer,定義如下:
|
||
```cpp
|
||
class BigBuffer {
|
||
public:
|
||
BigBuffer(int size=100*1024*1024) :
|
||
bufferSize(size)
|
||
{
|
||
std::cout << "BigBuffer constructor\n";
|
||
this->buffer = std::make_unique<uint8_t[]>(bufferSize);
|
||
}
|
||
|
||
~BigBuffer() {
|
||
std::cout << "BigBuffer destructor\n";
|
||
}
|
||
|
||
BigBuffer(const BigBuffer& src) {
|
||
std::cout << "BigBuffer copy constructor\n";
|
||
bufferSize = src.bufferSize;
|
||
buffer = std::make_unique<uint8_t[]>(bufferSize);
|
||
std::memcpy(buffer.get(), src.buffer.get(), bufferSize);
|
||
}
|
||
|
||
BigBuffer& operator= (BigBuffer& src) {
|
||
std::cout << "BigBuffer copy operator\n";
|
||
bufferSize = src.bufferSize;
|
||
buffer = std::make_unique<uint8_t[]>(bufferSize);
|
||
std::memcpy(buffer.get(), src.buffer.get(), bufferSize);
|
||
return *this;
|
||
}
|
||
|
||
private:
|
||
int bufferSize = 0;
|
||
std::unique_ptr<uint8_t[]> buffer = nullptr;
|
||
};
|
||
```
|
||
|
||
這個class的特色就是每一次使用都會佔用100MB的記憶體空間,想像下面的程式的動作:
|
||
```cpp
|
||
BigBuffer buf1;
|
||
// Do something with buf1
|
||
// Assign to buf2
|
||
BigBuffer buf2 = buf1;
|
||
```
|
||
|
||
這會先產生buf1,然後把buf1 copy給buf2。如果我們想要省下copy的成本,這時候 Move assignment operator(就是 `=`)就可以派上用場了。
|
||
幫
|
||
|
||
|
||
|
||
## 參考
|
||
- [Value categories - cppreference.com](https://en.cppreference.com/w/cpp/language/value_category)
|
||
- [rvalue 參考](https://openhome.cc/Gossip/CppGossip/RvalueReference.html) |