日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
關(guān)于C++默認(rèn)拷貝構(gòu)造函數(shù)產(chǎn)生的問題的討論

對(duì)于拷貝構(gòu)造函數(shù),我前面的博文有提起過,不過,有的時(shí)候,淺拷貝和深拷貝真的很難理解,所以,我們?cè)龠M(jìn)行關(guān)于拷貝構(gòu)造函數(shù)的一些討論。

大家都整到拷貝構(gòu)造函數(shù)分為淺拷貝深拷貝,系統(tǒng)默認(rèn)的拷貝構(gòu)造函數(shù)是淺拷貝。

默認(rèn)拷貝構(gòu)造函數(shù)以內(nèi)存拷貝的方式將舊有對(duì)象的內(nèi)存空間拷貝到新對(duì)象的內(nèi)存空間。

如果類中有指針類型的類型的時(shí)候,默認(rèn)拷貝構(gòu)造函數(shù)只能復(fù)制指針屬性的值,而不能復(fù)制指針屬性所指向的內(nèi)存,此時(shí),如果我們自己不顯式定義拷貝構(gòu)造函數(shù),那么我們?cè)诰幊痰臅r(shí)候,可能會(huì)出現(xiàn)很詭異的問題。

顯式定義拷貝構(gòu)造函數(shù)來完成指針屬性等需要特殊處理的屬性的拷貝工作。

The Number one :  我們先來看淺拷貝帶來的問題

---------------------我是分割線------------------------

 
 
  1. # include    
  2. using namespace std;   
  3.     
  4. class Car   
  5. {   
  6. private:   
  7.     char*  brand;   
  8.     float  price;   
  9. public:   
  10.     Car(const char* sz, float p)          
  11.     {   
  12.         //構(gòu)造函數(shù)中為brand分配內(nèi)存   
  13.         brand = new char[strlen(sz)+1];   
  14.         strcpy(brand, sz);   
  15.     }   
  16.     ~Car   
  17.     {   
  18.         //析構(gòu)函數(shù)中釋放申請(qǐng)的內(nèi)存   
  19.         delete[] brand;   
  20.         cout << " Clear is over ! " << endl;           
  21.     }   
  22.     void just_print()   
  23.     {   
  24.         cout << "brand : " << brand << endl;   
  25.         cout << "price : " << price << endl;   
  26.     }   
  27. };   
  28.     
  29. int main(void)   
  30. {   
  31.     Car car_one("BMW",120);   
  32.     car_one.just_print();   
  33.     //調(diào)用默認(rèn)的拷貝構(gòu)造函數(shù)   
  34.     Car car_two(comp_one);   
  35.     car_two.print();   
  36.     
  37.     return 0;   

----------------------------------------------------------------------------

這個(gè)程序運(yùn)行失敗,代碼分析:

1、car_two(car_one)等價(jià)于

         car_two.brand = car_one.brand;

         car_two.price  = car_one.price;

2、經(jīng)過賦值操作后,兩個(gè)對(duì)象中的指針指向的是同一塊動(dòng)態(tài)內(nèi)存,當(dāng)car_one和car_two撤銷時(shí),其釋放函數(shù)都要釋放同一塊動(dòng)態(tài)內(nèi)存內(nèi)存,可是,兩個(gè)對(duì)象撤銷有先有后,一旦一個(gè)對(duì)象被撤銷,另一個(gè)對(duì)象的brand指針變速"野指針",使用該指針再次釋放同一塊動(dòng)態(tài)內(nèi)存會(huì)引發(fā)內(nèi)存錯(cuò)誤。

不僅僅是重復(fù)釋放內(nèi)存的問題,還會(huì)出現(xiàn)其他問題:

-------------------------------------------------------------------------------

 
 
  1. int main(void)   
  2. {   
  3.     Car car_one("Dell", 7000);   
  4.         
  5.     if(true)   
  6.     {   
  7.         car car_two(car_one);   
  8.         car_two.print();   
  9.     }   
  10.     //car_one.brand指向的動(dòng)態(tài)內(nèi)存此時(shí)已經(jīng)被釋放   
  11.     car_one.print();   
  12.         
  13.     return 0;   

-------------------------------------------------------------------------------------------

由于car_two是在if結(jié)構(gòu)中定義的局部對(duì)象,因此if結(jié)構(gòu)退出時(shí),car_two被撤銷,系統(tǒng)自動(dòng)調(diào)用其析構(gòu)函數(shù),釋放了car_two.brand所指向的動(dòng)態(tài)內(nèi)存,由于car_one和car_two值相同,此時(shí)car_one.brand已無所指,成了野指針,此時(shí),對(duì)該指針的讀寫操作都會(huì)引發(fā)無法預(yù)料的錯(cuò)誤。

----------------------------------------------------------------------------

此時(shí),我們就需要自己來定義拷貝構(gòu)造函數(shù):

----------------------------------------------------------------------------

 
 
  1. //顯式定義構(gòu)造函數(shù)   
  2. # include    
  3. # include    
  4. using namespace std;   
  5.     
  6. class Car   
  7. {   
  8. private:   
  9.     char*    brand;   
  10.     float    price;   
  11. public:   
  12.     Car(const char*  sz, float  p)       
  13.     {   
  14.     brand = new char[strlen(sz)+1];   
  15.         strcpy(brand, sz);   
  16.         price = p;           
  17.     }   
  18.     //自定義拷貝構(gòu)造函數(shù)   
  19.     Car(const  Car&  cp)   
  20.     {   
  21.     //重新為brand開辟與cp.brand同等大小的內(nèi)存空間   
  22.     brand = new char[strlen(cp.brand) + 1];   
  23.         //   
  24.         strcpy(brand, cp.brand);   
  25.         price = cp.price;           
  26.     }   
  27.     ~Car()   
  28.     {   
  29.     delete[]  brand;   
  30.         cout << "clear over " <
  31.     }   
  32.         
  33.     void print()   
  34.     {   
  35.     cout << "brand " << endl;   
  36.         cout << "price " << endl;    
  37.     }       
  38. };   
  39.     
  40. int main(void)   
  41. {   
  42.     Car car_one("Dell", 8999);   
  43.     car_one.print();   
  44.     //   
  45.     Car car_two(car_one);   
  46.     car_two.print();   
  47.     //沒有采用brand = cp.brand 這種直接直接賦值,而是重新申請(qǐng)動(dòng)態(tài)內(nèi)存,使用   
  48.     //庫(kù)函數(shù)strcpy實(shí)現(xiàn)了字符串的復(fù)制   
  49.     //car_one.brand和car_two.brand指向兩塊不同的內(nèi)存,避免了錯(cuò)誤   
  50.              
  51.     return 0;   

------------------------------------------------------------------------------------------

***提一點(diǎn),自定義的拷貝構(gòu)造函數(shù),***也重載operator=運(yùn)算符!

-----------------------------------------------------------------------------------------

51cto博客:http://liam2199.blog./2879872/1417892


網(wǎng)站欄目:關(guān)于C++默認(rèn)拷貝構(gòu)造函數(shù)產(chǎn)生的問題的討論
網(wǎng)頁(yè)網(wǎng)址:http://www.dlmjj.cn/article/dpopgic.html