std::move
不會做任何東西的對象,它所做的就是通過引用轉發它的參數,並使它像一個右值綁定。換句話說,它只是返回一個匿名右值引用的對象,認爲:
template<class T>
T&& std::move(T&& arg)
{
return static_cast<T&&>(arg);
}
(這是比這稍微複雜一些,但我的目標是爲了便於閱讀)
什麼實際發生在這裏出口是:
CBuffer rv(std::move(out));
return rv;
這是調用CBuffer的移動構造函數。
很多人陷入思維std :: move的陷阱實際上執行的舉動,恕我直言,它的名字很差。
如果你寫的代碼是這樣的:
CBuffer BufferReader::read(const int size)
{
CBuffer out(read_raw(), size, true);
skip(size);
return out;
}
那麼大多數編譯器應該能夠執行「返回值優化」;也就是說,他們會悄悄假裝你做了等同於:
void BufferReader::read(const int size, CBuffer* out)
{
new (out) CBuffer(read_raw(), size, true); //in-place new
skip(size);
}
,並在您有
CBuffer x = reader.read(size);
調用網站,他們會假裝你正在寫
CBuffer* x = (CBuffer*)alloca(sizeof(CBuffer));
reader.read(size, &x);
再次簡化一下,上面的代碼是在棧上分配一個CBuffer,然後在被調用者內部初始化它。這節省了在回報中執行副本。
理論上返回使得副本返回,所以原理在理論上被破壞。給定一個正確定義的類,這不是一個問題。 – chris
除非[RVO](http://en.wikipedia.org/wiki/Return_value_optimization)進來,它應該在複製/移動後調用析構函數。 –
爲什麼不展示CBuffer類的基礎知識?不是每個函數,而是這裏使用的構造函數,複製構造函數,析構函數和關鍵數據成員?您可能會得到有關如何改進複製構造函數以實現此功能的有用建議。 – NicholasM