Move語義
- copy數(shù)據(jù)量大的對象很昂貴.
- 解決問題的方法有兩種: shallow copy或者deep copy
- shallow copy可以用類似
v = w
,讓v/w共享數(shù)據(jù). 但是shallow copy需要程序員額外的維護共享數(shù)據(jù)的reference counter,才能讓資源得到合理的釋放.
- deep copy則需要提供一種類似
copy(v, w)
的接口來完成,這時候v/w有各自的數(shù)據(jù).
- 講道理,這個故事就應(yīng)該完了,但是c++發(fā)現(xiàn)了可以優(yōu)化的點.
- 比如,一個局部變量作為函數(shù)返回值, 按道理洗需要deep copy的,但是我們發(fā)現(xiàn)其實把該局部變量的數(shù)據(jù)直接就transfer給target object就更加的高效了.
- 需要說明的是,這仍然是一種deep copy.
move構(gòu)造函數(shù)
class vector {
vector(vector&& v) : my_size(v.my_size), data(v.data) {
v.data = 0; v.my_size = 0;
}
}
- move ctor從source 偷取data, source 變成了空的對象.
- 被當(dāng)做rvalue傳遞給函數(shù)的變量理論上來說在函數(shù)調(diào)用結(jié)束的時候就應(yīng)該銷毀的. 也就是說該變量狀態(tài)應(yīng)該清零.
- 當(dāng)有指針的時候尤其要注意,不能是一個隨機的地址,否則在dtor的時候會出出錯.
- 有的時候明明是一個lvalue,但是這個對象就要過期了,想把資源transfer出去,怎么借用move ctor呢? 答案就是std::move()
move賦值構(gòu)造函數(shù)
- move 賦值構(gòu)造常用swap機制來實現(xiàn),也就是說把source和target的東西呼喚,當(dāng)source對象析構(gòu)的時候?qū)嶋H銷毀的是當(dāng)前對象的東西(貌似也沒什么用)
- 為什么這里選擇交換而不是初始化呢?其實是一樣的把....只不過更加精簡的實現(xiàn)
class vector {
vector& operator=(vector&& src) {
assert(my_size == 0 || my_siz == src.my_size);
std::swap(data, src.data);
return *this;
}
};
- 但是實際的時候有一種叫做copy ellsion的方法,編譯器會自動優(yōu)化掉函數(shù)傳遞變量的問題.
move語義什么時候用呢?
- 有了std::move,那么move語義跟unique_ptr有什么差別呢? 好像都是讓資源只有一份copy.
- 另一種場景是說std::move之后的src對象就過期了.
- ????? 沒解釋清楚