現在有這麼幾個結構體:
typedef struct _info_headinfo_head;typedef struct _pkt_info pkt_info;
typedef struct _pkt pkt;
雖然這幾個結構體都是由基本型別構成的,而且也不涉及動態記憶體管理,但是體積確實是有一點的。其中info_head是16位元組,pkt_info是24個位元組,那麼乙個pkt就是40個位元組啦。這還只是在32位的機器上的情況。
之後我們又遇到了乙個這樣的類,這個類使用list容器,儲存了多個pkt型別的變數。
class pkt_list;
pkt tmp;
tmp.head = head;
tmp.info = info;
head_to_pkt.push_back(tmp);
return 1;
}由於pkt只包含基本型別,所以直接用就好啦,不用new,也不用擔心記憶體管理的問題。
這裡我們看到了第乙個問題,要想把一組info_head和pkt_info型別的變數合併成乙個pkt型別的變數,就必須重新組建乙個pkt型別的變數。就是說,記憶體中已經有了16b的info_head和24b的pkt_info之後,但是還要再使用40b去儲存和前邊一對變數值完全相同的乙個pkt型別的變數。雖然有浪費記憶體的嫌疑,但這個是避免不了的,因為我們沒法保證之前的那兩個16b和24b的東西就挨在一起。所以其實也不能算是浪費。
那麼這樣算下來,我們已經用了120b的記憶體來儲存同一段資料了。這樣確實是乙個很浪費的舉動。但是在c++14出現之前,我們無能為力。
c++14中提出了右值引用的概念,也叫move語義。具體怎麼個意義就不說了,直接說效果,那就是可以省下40b的開銷。但這是咋做到的呢?很簡單,就是直接把第二次的那40b直接移入容器中就可以了,而不是再拷貝複製一次。這麼說來,list::push_back(t&);就應該又另乙個更高效的版本了,那就是list::push_back(t&&);。總的來說,stl有得重寫了。
接下來,為了使用第二個版本的push_back函式的過載,我們必須在引數列表裡寫上作為右值的無名變數,但是如果已經使用了乙個暫存器變數tmp,那麼這40b的開銷是無論如何也省不下來的,因此tmp已經有了名字,就不再是右值了。而要想得到pkt型別的無名變數,就要重新為pkt寫乙個建構函式了。全部改完之後,大概是這個樣子的。
class pktpkt(const info_head &h, const pkt_info i):
head(h), info(i){}
info_head head;
pkt_info info;
};...
head_to_pkt.push_back( pkt( head, info ) );
//with move semantics version being used, it works.
return 1;
}
ok。就總結這麼多。
c 的右值引用
關於右值引用,這個技術是用於處理臨時物件的析構問題。之前也考慮過臨時物件的析構問題。考慮這麼乙個問題。class house house const house h house house build house h int main 編譯 g c house.cpp std c 11 o a 最終...
關於c 的 右值 右值引用 move
第一次接觸c move操作就懵逼了,一直想探個究竟,但是右值以及右值引用思考了好長時間,就是不得要領,今天終於有所收穫,寫下第一篇部落格,一方面為了幫助一些剛入門的朋友,另一方面也是幫助自己今後複習。左值是乙個持久的量,右值是乙個短暫的量。那怎麼算持久怎麼算短暫呢?取決於我的 裡有沒有乙個變數來儲存...
面試題 什麼是右值引用?右值引用與左值引用的區別
什麼是左值引用呢?左值引用,就是繫結到左值的引用,通過 來獲得左值引用。那麼,什麼是左值呢?左值,就是在記憶體有確定儲存位址 有變數名,表示式結束依然存在的值。左值可以分為兩類 非常量左值和常量左值 同理,右值也可以分為兩類 非常量右值和常量左值。左值引用舉例說明 int a 10 非常量左值 有確...