日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

剖析——移动构造函数

發(fā)布時(shí)間:2024/1/17 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 剖析——移动构造函数 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

移動(dòng)構(gòu)造函數(shù)應(yīng)用的場(chǎng)景????

答:有時(shí)候我們會(huì)遇到這樣一種情況,我們用對(duì)象a初始化對(duì)象b,后對(duì)象a我們就不在使用了,但是對(duì)象a的空間還在呀(在析構(gòu)之前),既然拷貝構(gòu)造函數(shù),實(shí)際上就是把a(bǔ)對(duì)象的內(nèi)容復(fù)制一份到b中,那么為什么我們不能直接使用a的空間呢?這樣就避免了新的空間的分配,大大降低了構(gòu)造的成本。這就是移動(dòng)構(gòu)造函數(shù)設(shè)計(jì)的初衷。

?

例子示下:

#include<string> #include<vector> using namespace std;class String; ostream& operator<<(ostream& out, String& s); class String { public:friend ostream& operator<<(ostream& out, String& s); public:String(const char* data = ""){if (data == NULL){m_data = new char[1];m_data[0] = '\0';}else{m_data = new char[strlen(data) + 1];strcpy(m_data, data);}cout << "constructor execute..." << endl;}String(String &&s)noexcept{cout << "move constructor execute..." << endl;m_data = NULL;this->m_data = s.m_data;s.m_data = NULL;}~String(){cout << this<<"free execute..." << endl;if(m_data != NULL)delete[] m_data;} private:char* m_data; };ostream& operator<<(ostream& out, String& s) {out << s.m_data;return out; } int main() {String s = "hello";vector<String> vs(1);vs.push_back(std::move(s));return 0; }

執(zhí)行結(jié)果:

解析運(yùn)行結(jié)果:

1、第一個(gè) “默認(rèn)構(gòu)造函數(shù)” 是因?yàn)関ector<String> vs(1) , 所以事先使用默認(rèn)構(gòu)造函數(shù)構(gòu)造了一個(gè)Test對(duì)象

2、第二個(gè) “默認(rèn)構(gòu)造函數(shù)” 是因?yàn)門est t ,使用默認(rèn)構(gòu)造函數(shù)構(gòu)造了一個(gè)對(duì)象

3、第三個(gè) “移動(dòng)構(gòu)造函數(shù)” 大多數(shù)人會(huì)以為是 vec.push_back(std::move(s)) ,push_back 導(dǎo)致對(duì)象的移動(dòng)而輸出的。具體的原因其實(shí)是由于重新分配內(nèi)存而導(dǎo)致的,我們的 vector 對(duì)象 vs 初始的容量只有 1 ,且里面已經(jīng)有一個(gè)對(duì)象了,就是vector<Test> vs(1)的時(shí)候創(chuàng)建的,所以再向vs里面添加String對(duì)象時(shí),就會(huì)導(dǎo)致vs重新分配內(nèi)存。由于vs中的對(duì)象定義了移動(dòng)構(gòu)造函數(shù)且是可用的(因?yàn)槲覀儗⑵渎暶鳛榱薾oexcept),所以就會(huì)調(diào)用移動(dòng)構(gòu)造函數(shù)將vs中原始的那個(gè)對(duì)象移動(dòng)到新的內(nèi)存中,從而輸出 “移動(dòng)構(gòu)造函數(shù)”。

4、第四個(gè) “移動(dòng)構(gòu)造函數(shù)” 才是因?yàn)镾tring對(duì)象 t 被移動(dòng)到vector 對(duì)象 vs 新的空間而輸出的

5、第五個(gè) “析構(gòu)函數(shù)” 是因?yàn)橹匦路峙鋬?nèi)存后,原來(lái)的內(nèi)存將被銷毀,所以輸出一個(gè)“析構(gòu)函數(shù)”

6、后面三個(gè) “析構(gòu)函數(shù)” 是因?yàn)閳?zhí)行了return 0, 內(nèi)存被釋放,vs 和 s 都被析構(gòu),所以輸出三個(gè) “析構(gòu)函數(shù)

?

注意:

第四行的輸出由 “移動(dòng)構(gòu)造函數(shù)” 變成了 “拷貝構(gòu)造函數(shù)” ,原因是:

由于我們的移動(dòng)構(gòu)造函數(shù)沒(méi)有聲明為noexcept,所以我們的移動(dòng)構(gòu)造函數(shù)就會(huì)被認(rèn)為是可能拋出異常,所以在重新分配內(nèi)存的過(guò)程中,vs對(duì)象就會(huì)使用拷貝構(gòu)造函數(shù)來(lái)“移動(dòng)”對(duì)象(這里說(shuō)的移動(dòng)其實(shí)是拷貝,并不是移動(dòng)),所以就輸出了“拷貝構(gòu)造函數(shù)”。

?

轉(zhuǎn)載于:https://www.cnblogs.com/single-dont/p/11328524.html

總結(jié)

以上是生活随笔為你收集整理的剖析——移动构造函数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。