chp4-類的高級(jí)特性_第1頁
chp4-類的高級(jí)特性_第2頁
chp4-類的高級(jí)特性_第3頁
chp4-類的高級(jí)特性_第4頁
chp4-類的高級(jí)特性_第5頁
已閱讀5頁,還剩23頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第四章類的高級(jí)特性第四章類的高級(jí)特性24.1案例-鏈表類的復(fù)制問題4.1.1案例及其實(shí)現(xiàn)復(fù)雜類型的復(fù)制操作a:1b:2.3a:?b:?o1o2復(fù)制復(fù)制的兩種方式:Xo2{o1};o2=o1;a:1b:2.3可以視為是內(nèi)存復(fù)制第四章類的高級(jí)特性linked_list::linked_list():head(nullptr),tail(nullptr),_size(0){std::cout<<"indefaultconstructor"<<std::endl;}

linked_list::linked_list(conststd::initializer_list<value_t>&l):head(nullptr),tail(nullptr),_size(0){for(autoe:l)push_back(e);std::cout<<"inlistconstructor"<<std::endl;}

linked_list::~linked_list(){clear();std::cout<<"indestructor"<<std::endl;}34.1案例-鏈表類的復(fù)制問題4.1.1案例及其實(shí)現(xiàn)鏈表的構(gòu)造函數(shù)和析構(gòu)函數(shù)第四章類的高級(jí)特性voidlinked_list::peer(){std::cout<<"|"<<head<<''<<tail<<''<<_size<<std::endl;}intmain(){autoaf=[](value_t&v){std::cout<<v<<'';};linked_listl1{1,2,3,4,5};//定義對(duì)象并初始化std::cout<<"l1:";l1.traverse(af);l1.peer();

linked_listl2{l1};//初始化復(fù)制std::cout<<"l2:";l2.traverse(af);l2.peer();

return0;}44.1案例-鏈表類的復(fù)制問題4.1.1案例及其實(shí)現(xiàn)鏈表的復(fù)制—初始化時(shí)有兩個(gè)對(duì)象定義,因此應(yīng)該有兩條構(gòu)造和析構(gòu)信息inlistconstructorl1:12345|0x6020000000100x6020000000905l2:12345|0x6020000000100x6020000000905indestructor===================================================================5430==ERROR:AddressSanitizer:attemptingdouble-freeon0x602000000010inthreadT0:#00x7fe3dff1e0f8inoperatordelete(void*,unsignedlong)../../../../libsanitizer/asan/asan_new_delete.cc:151#10x40100finlinked_list::clear()…//此后是詳細(xì)的診斷信息,故略去第四章類的高級(jí)特性voidlinked_list::peer(){std::cout<<"|"<<head<<''<<tail<<''<<_size<<std::endl;}intmain(){autoaf=[](value_t&v){std::cout<<v<<'';};linked_listl1{1,2,3,4,5};//定義對(duì)象并初始化std::cout<<"l1:";l1.traverse(af);l1.peer();

linked_listl2;

l2

=

l1;

//賦值std::cout<<"l2:";l2.traverse(af);l2.peer();

return0;}54.1案例-鏈表類的復(fù)制問題4.1.1案例及其實(shí)現(xiàn)鏈表的復(fù)制—賦值時(shí)有兩個(gè)對(duì)象定義,因此應(yīng)該有兩條構(gòu)造和析構(gòu)信息inlistconstructorl1:12345|0x6020000000100x6020000000905indefaultconstructorl2:12345|0x6020000000100x6020000000905indestructor===================================================================5430==ERROR:AddressSanitizer:attemptingdouble-freeon0x602000000010inthreadT0:#00x7fe3dff1e0f8inoperatordelete(void*,unsignedlong)../../../../libsanitizer/asan/asan_new_delete.cc:151#10x40100finlinked_list::clear()…//此后是詳細(xì)的診斷信息,故略去第四章類的高級(jí)特性代碼分析鏈表類有兩個(gè)以上的構(gòu)造函數(shù)main中定義了l1和l2兩個(gè)對(duì)象預(yù)期結(jié)果兩條構(gòu)造信息兩條析構(gòu)信息結(jié)果表現(xiàn)出的問題只有一條構(gòu)造信息只有一條析構(gòu)信息64.1案例-鏈表類的復(fù)制問題4.1.2案例問題分析初始化的情況只有一條構(gòu)造信息:l2的構(gòu)造函數(shù)沒有被調(diào)用嗎?答案:不可能!因?yàn)闃?gòu)造函數(shù)調(diào)用是編譯器的強(qiáng)制行為。解釋:顯式定義的構(gòu)造函數(shù)沒有一個(gè)被調(diào)用,那么只有一個(gè)可能,編譯器自己合成了一個(gè),并且調(diào)用了它!第四章類的高級(jí)特性分析:那么這個(gè)合成的構(gòu)造函數(shù)的原型是什么?初始化時(shí),用一個(gè)已存在的對(duì)象去初始化一個(gè)正在構(gòu)建的對(duì)象。顯然,這個(gè)構(gòu)造函數(shù)的參數(shù)的類型是這種類本身(的引用)。這種構(gòu)造函數(shù)稱為“復(fù)制構(gòu)造函數(shù)(copyconstructor)”。合成的復(fù)制構(gòu)造函數(shù)完成了逐成員的復(fù)制。這可以理解為源對(duì)象的內(nèi)存復(fù)制到目標(biāo)對(duì)象的內(nèi)存中。74.1案例-鏈表類的復(fù)制問題4.1.2案例問題分析初始化的情況第四章類的高級(jí)特性合成的復(fù)制構(gòu)造函數(shù)完成了兩個(gè)對(duì)象的復(fù)制。84.1案例-鏈表類的復(fù)制問題4.1.2案例問題分析初始化的情況1

2

3

4

5^headtaill1headtaill2復(fù)制使兩個(gè)對(duì)象共享了存儲(chǔ)第四章類的高級(jí)特性程序結(jié)束時(shí),l2先析構(gòu)。94.1案例-鏈表類的復(fù)制問題4.1.2案例問題分析初始化的情況1

2

3

4

5^headtaill1head:^tail:^l2l2釋放了儲(chǔ)存,導(dǎo)致l1的兩個(gè)指針指向了無效地址,成為懸空指針。因此,當(dāng)l1試圖(再次)釋放內(nèi)存是就會(huì)發(fā)生致命錯(cuò)誤。第四章類的高級(jí)特性代碼分析鏈表類有兩個(gè)以上的構(gòu)造函數(shù)main中定義了l1和l2兩個(gè)對(duì)象預(yù)期結(jié)果兩條構(gòu)造信息兩條析構(gòu)信息結(jié)果表現(xiàn)出的問題有兩條構(gòu)造信息只有一條析構(gòu)信息104.1案例-鏈表類的復(fù)制問題4.1.2案例問題分析賦值的情況有兩條構(gòu)造信息:l2被正確構(gòu)造了。但只有一條析構(gòu)信息。顯然,其中的一個(gè)對(duì)象在析構(gòu)時(shí)出錯(cuò)。出錯(cuò)的原因與初始化時(shí)一樣。第四章類的高級(jí)特性常見的復(fù)制會(huì)發(fā)生在這些場(chǎng)合:對(duì)象初始化時(shí)linked_listl2{l1};//直接初始化linked_listl3=l1;//復(fù)制初始化2.函數(shù)參數(shù):value,notpointer/referencevoidf(linked_listl);linked_listx;f(x);3.函數(shù)返回:value,notpointer/referencelinked_listg(){returnlinked_list({1,2,3});}autoy=g();114.2復(fù)制控制4.2.1復(fù)制在這些場(chǎng)合中,復(fù)制構(gòu)造函數(shù)起了重要作用。linked_list::linked_list(constlinked_list&l):head(l.head),tail(l.tail),_size(l._size){}//注:第一個(gè)參數(shù)實(shí)際上可以是本類型任意類型的引用第四章類的高級(jí)特性重載的賦值運(yùn)算符函數(shù)

T&T::operator=(constT&rhs);124.2復(fù)制控制4.2.2賦值linked_list&linked_list::operator=(constlinked_list&l){clear();//釋放現(xiàn)有的所有節(jié)點(diǎn)

head=l.head;tail=l.tail_size=l._size;

return*this;//返回對(duì)象本身}linked_list(constlinked_list&l):head(l.head),tail(l.tail),_size(l._size){}第四章類的高級(jí)特性134.2復(fù)制控制4.2.2賦值復(fù)制和賦值的異同To1,o2;o2=o1;發(fā)生在賦值(運(yùn)行)時(shí)左操作對(duì)象已經(jīng)存在。它可能已經(jīng)擁有了資源,需要在賦值時(shí)先釋放賦值運(yùn)算可以級(jí)聯(lián)。因此函數(shù)應(yīng)該返回左操作對(duì)象的引用。VS復(fù)制賦值To2{o1},o3=o1;發(fā)生在初始化(編譯)時(shí)左操作對(duì)象正在被構(gòu)建,不擁有資源復(fù)制無需返回任何值第四章類的高級(jí)特性144.2復(fù)制控制4.2.3淺復(fù)制和深復(fù)制淺復(fù)制已經(jīng)存在的對(duì)象l1資源ra)復(fù)制前創(chuàng)建成功的對(duì)象l2已經(jīng)存在的對(duì)象l1資源rb)復(fù)制后:資源共享正在創(chuàng)建的對(duì)象l2沒有資源依然存在的對(duì)象l1率先失效的對(duì)象l2資源r被l2釋放c)對(duì)象l2失效后?第四章類的高級(jí)特性154.2復(fù)制控制4.2.3淺復(fù)制和深復(fù)制深復(fù)制已經(jīng)存在的對(duì)象l1資源r1a)復(fù)制前創(chuàng)建成功的對(duì)象l2已經(jīng)存在的對(duì)象l1資源r1b)復(fù)制后:資源不共享正在創(chuàng)建的對(duì)象l2沒有資源依然存在的對(duì)象l1率先失效的對(duì)象l2資源r1的副本被釋放c)對(duì)象l2失效后資源r1的副本資源r1linked_list::linked_list(constlinked_list&l):head(nullptr),tail(nullptr),_size(0){

for(node_ptrp=l.head;p!=nullptr;p=p->next)push_back(p->data);}第四章類的高級(jí)特性164.2復(fù)制控制4.2.3淺復(fù)制和深復(fù)制優(yōu)缺點(diǎn)對(duì)比代價(jià)較高。需要考慮復(fù)制的深度??赡懿恍枰Y源共享安全風(fēng)險(xiǎn)較低VS淺復(fù)制深復(fù)制代價(jià)較小可能導(dǎo)致資源共享安全風(fēng)險(xiǎn)較高第四章類的高級(jí)特性174.2復(fù)制控制4.2.4轉(zhuǎn)移對(duì)象和轉(zhuǎn)移語義可能的復(fù)制路徑classobject{…};objectf(){objectt;

returnt;}//返回局部對(duì)象的值autoa=f();復(fù)制復(fù)制t資源r匿名臨時(shí)對(duì)象r的副本a資源sr的副本這個(gè)過程有問題嗎?第四章類的高級(jí)特性184.2復(fù)制控制4.2.4轉(zhuǎn)移對(duì)象和轉(zhuǎn)移語義效率問題復(fù)制復(fù)制t資源r匿名臨時(shí)對(duì)象r的副本a資源sr的副本這個(gè)對(duì)象在復(fù)制后失效,資源被釋放這個(gè)資源在復(fù)制時(shí)釋放這個(gè)資源是復(fù)制而來這正是(早期的)C++被詬病的問題之一。有無好辦法解決這類效率問題呢?第四章類的高級(jí)特性194.2復(fù)制控制4.2.4轉(zhuǎn)移對(duì)象和轉(zhuǎn)移語義解決思路復(fù)制復(fù)制t資源r匿名臨時(shí)對(duì)象r的副本a資源sr的副本直接“轉(zhuǎn)移”給a資源s轉(zhuǎn)移給轉(zhuǎn)義對(duì)象去釋放這類即將失效(expiring)的對(duì)象稱為“轉(zhuǎn)移對(duì)象”,用右值引用標(biāo)記第四章類的高級(jí)特性204.2復(fù)制控制4.2.4轉(zhuǎn)移對(duì)象和轉(zhuǎn)移語義編碼實(shí)現(xiàn)linked_list&operator=(linked_list&&l){

std::swap(head,l.head);std::swap(tail,l.tail);std::swap(_size,l._size);

return*this;}轉(zhuǎn)移復(fù)制構(gòu)造函數(shù)轉(zhuǎn)移賦值運(yùn)算符函數(shù)linked_list(linked_list&&l):head(l.head),tail(l.tail),_size(l._size){

l.head=l.tail=nullptr;l._size=0;}第四章類的高級(jí)特性私有構(gòu)造函數(shù),但僅聲明,無實(shí)現(xiàn)linked_list(constlinked_list&);禁止合成linked_list(constlinked_list&)=delete;linked_list&operator=(constlinked_list&l)=delete;214.2復(fù)制控制4.2.5禁止復(fù)制第四章類的高級(jí)特性概念類型名類名::*指針;類型名(類名::*指針)(參數(shù)列表);初始化指針=&類名::成員名;使用對(duì)象.*指針;對(duì)象->*指針;224.3指向類成員的指針4.2.5禁止復(fù)制第四章類的高級(jí)特性初衷僅僅出于效率的考慮。原則一個(gè)類的友元可以直接訪問它的所有成員。234.4友元class類名A{

//othermembers;

friend函數(shù)原型聲明;//全局友元函數(shù)聲明

friend類名B::成員函數(shù)原型聲明;//成員函數(shù)友元聲明

friend[class]類名C;//友元類聲明//友元聲明放在哪個(gè)段無關(guān)緊要};友元特性:非傳遞性非對(duì)稱性第四章類的高級(jí)特性classX{private:

constinta;//如果沒有初始化,那么只能在構(gòu)造函數(shù)的初始化列表里進(jìn)行

constintc=1;//OKintb;

public:X(inti,intj):a(i),b(j){}constintget_c()const{returnc;}};244.5常量和mutable成員4.5.1常量成員第四章類的高級(jí)特性classY{public:Y():x(0),y(0){}intx;

mutableinty;};

constYo;o.x=1;//erroro.y=2;//OK254.5常量和mutable成員4.5.2mutable成員第四章類的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論