c 11 移動語意 gcc 實測

2021-07-03 11:48:42 字數 3357 閱讀 9077

使用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庫,可以寫一些可移植的使用右值引用的 左值 乙個函式或者物件例項。失效值 生命期即將結束的物件。廣義左值 包括左值和失效值。右值 ...