使用gcc,對c++11中的 移動語意進行實際效果測試
class a
a(a&& a)
a(const a& a)
a(a& a)
~a()
static a func(void)
static a&& func2(void)
};int main(int argc, char* argv)
}
在gcc下編譯,測試結果:
const a& a = func();
construction: default
destory
const a&& a = func();
construction: default
destory
a a = func();
construction: default
destory
const a& a = func2();
construction: default
destory
const a&& a = func2();
construction: default
destory
a a = func2();
construction: default
destory
construction: move
destory
例項1 結果分析:
對於函式返回臨時變數的情況,沒有必要用move語意。 編譯器會自己優化來沒有任何物件拷貝.
class vec
vec(vec&& a)
vec(const vec& a)
~vec()
void operator=(const vec& a)
void operator=(vec&& a)
size_t size() const
void clear()
private:
std::vectorv_;
};
vec類包裹 std::vector是為了暴露出呼叫了vector的哪些函式。 真實**,是沒有vec類,下面的b類直接擁有std::vector
class b
vec grab_all1()
vec grab_all2()
vec grab_all3()
vec&& grab_all4()
vec v_;
};
vec grab_all1()
grab_all1展示了我們的需求。
測試**:
std::cout << std::endl << "vec& v = b.grab_all1" << std::endl;
b b;
const vec& v = b.grab_all1();
std::cout << "b size: " << b.size() << " v size: " << v.size() << std::endl;
返回:
vec& v = b.grab_all1
construction: default
construction: const copy
clear
b size: 0 v size: 2
destory
destory
vec grab_all2()
vec grab_all3()
測試**:
返回:
vec&& v = b.brab_all2
construction: default
construction: move
b size: 0 v size: 2
destory
destory
vec v = b.brab_all2
construction: default
construction: move
b size: 0 v size: 2
destory
destory
vec&& v = b.brab_all3
construction: default
construction: move
b size: 0 v size: 2
destory
destory
vec v = b.brab_all3
construction: default
construction: move
b size: 0 v size: 2
destory
destory
可以看出兩種方式一致,都達到了move語意。 (賦值函式被優化為直接拷貝建構函式)。
vec&& grab_all4()
測試**:
結果:
vec v = b.brab_all4
construction: default
construction: move
b size: 0 v size: 2
destory
destory
vec&& v = b.brab_all4
construction: default
b size: 2 v size: 2
destory
vec&& v = b.brab_all4; v2 = v
construction: default
construction: const copy
b size: 2 v size: 2
destory
destory
const vec& v = b.brab_all4
construction: default
b size: 2 v size: 2
destory
發現brab_all4不人為在外面增加一次拷貝的話,無法達到將資料移出的效果 (引起了隱晦的bug)
因此不要將成員變數以右值引用暴露出來。
實測,應該使用第2,3種方案.
c 11 移動語義
右值是相對於左值而言的。簡單來說,在等號左邊的叫做左值,等號右邊的叫做右值。再具體點說,左值是值能夠取位址的值,比如我們定義的變數這些都是能夠賦值並且能夠取位址的。而右值是不能夠取位址的,比如常量 hello 或者乙個臨時變數。在c 11之前我們如何實用右值呢?通常是使用常引用,const type...
c 11 移動語義
c 已經擁有了拷貝建構函式,和賦值函式,它們主要定位為淺和深度拷貝,新增加乙個移動建構函式,主要避免拷貝構造。在定義了移動建構函式的情況下,在實參 argument 是乙個右值 rvalue,包括xvalue和prvalue 的情況下會呼叫移動建構函式,而不是呼叫複製建構函式 可以使用std mov...
使用C 11移動複製
製作乙個可移植的使用右值引用的類 c 11標準的最大功能之一是右值引用。此功能允許修改臨時物件,從它們那裡 偷 資源。在c 03中沒有有值引用,但使用boost.move庫,可以寫一些可移植的使用右值引用的 左值 乙個函式或者物件例項。失效值 生命期即將結束的物件。廣義左值 包括左值和失效值。右值 ...