最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解C++ 拷貝構(gòu)造函數(shù)和賦值運(yùn)算符

 更新時(shí)間:2016年12月08日 14:12:55   作者:Brook_icv  
本文主要介紹了拷貝構(gòu)造函數(shù)和賦值運(yùn)算符的區(qū)別,以及在什么時(shí)候調(diào)用拷貝構(gòu)造函數(shù)、什么情況下調(diào)用賦值運(yùn)算符。最后,簡單的分析了下深拷貝和淺拷貝的問題。有需要的朋友可以看下

本文主要介紹了拷貝構(gòu)造函數(shù)和賦值運(yùn)算符的區(qū)別,以及在什么時(shí)候調(diào)用拷貝構(gòu)造函數(shù)、什么情況下調(diào)用賦值運(yùn)算符。最后,簡單的分析了下深拷貝和淺拷貝的問題。

拷貝構(gòu)造函數(shù)和賦值運(yùn)算符

在默認(rèn)情況下(用戶沒有定義,但是也沒有顯式的刪除),編譯器會(huì)自動(dòng)的隱式生成一個(gè)拷貝構(gòu)造函數(shù)和賦值運(yùn)算符。但用戶可以使用delete來指定不生成拷貝構(gòu)造函數(shù)和賦值運(yùn)算符,這樣的對(duì)象就不能通過值傳遞,也不能進(jìn)行賦值運(yùn)算。

class Person
{
public:
 Person(const Person& p) = delete;
 Person& operator=(const Person& p) = delete;
private:
 int age;
 string name;
};

上面的定義的類Person顯式的刪除了拷貝構(gòu)造函數(shù)和賦值運(yùn)算符,在需要調(diào)用拷貝構(gòu)造函數(shù)或者賦值運(yùn)算符的地方,會(huì)提示_無法調(diào)用該函數(shù),它是已刪除的函數(shù)_。

還有一點(diǎn)需要注意的是,拷貝構(gòu)造函數(shù)必須以引用的方式傳遞參數(shù)。這是因?yàn)椋谥祩鬟f的方式傳遞給一個(gè)函數(shù)的時(shí)候,會(huì)調(diào)用拷貝構(gòu)造函數(shù)生成函數(shù)的實(shí)參。如果拷貝構(gòu)造函數(shù)的參數(shù)仍然是以值的方式,就會(huì)無限循環(huán)的調(diào)用下去,直到函數(shù)的棧溢出。

何時(shí)調(diào)用

拷貝構(gòu)造函數(shù)和賦值運(yùn)算符的行為比較相似,都是將一個(gè)對(duì)象的值復(fù)制給另一個(gè)對(duì)象;但是其結(jié)果卻有些不同,拷貝構(gòu)造函數(shù)使用傳入對(duì)象的值生成一個(gè)新的對(duì)象的實(shí)例,而賦值運(yùn)算符是將對(duì)象的值復(fù)制給一個(gè)已經(jīng)存在的實(shí)例。這種區(qū)別從兩者的名字也可以很輕易的分辨出來,拷貝構(gòu)造函數(shù)也是一種構(gòu)造函數(shù),那么它的功能就是創(chuàng)建一個(gè)新的對(duì)象實(shí)例;賦值運(yùn)算符是執(zhí)行某種運(yùn)算,將一個(gè)對(duì)象的值復(fù)制給另一個(gè)對(duì)象(已經(jīng)存在的)。調(diào)用的是拷貝構(gòu)造函數(shù)還是賦值運(yùn)算符,主要是看是否有新的對(duì)象實(shí)例產(chǎn)生。如果產(chǎn)生了新的對(duì)象實(shí)例,那調(diào)用的就是拷貝構(gòu)造函數(shù);如果沒有,那就是對(duì)已有的對(duì)象賦值,調(diào)用的是賦值運(yùn)算符。

調(diào)用拷貝構(gòu)造函數(shù)主要有以下場(chǎng)景:

  • 對(duì)象作為函數(shù)的參數(shù),以值傳遞的方式傳給函數(shù)?!?/li>
  • 對(duì)象作為函數(shù)的返回值,以值的方式從函數(shù)返回
  • 使用一個(gè)對(duì)象給另一個(gè)對(duì)象初始化

代碼如下:

class Person
{
public:
 Person(){}
 Person(const Person& p)
 {
 cout << "Copy Constructor" << endl;
 }
 Person& operator=(const Person& p)
 {
 cout << "Assign" << endl;
 return *this;
 }
private:
 int age;
 string name;
};
void f(Person p)
{
 return;
}
Person f1()
{
 Person p;
 return p;
}
int main()
{
 Person p;
 Person p1 = p; // 1
 Person p2;
 p2 = p; // 2
 f(p2); // 3
 p2 = f1(); // 4
 Person p3 = f1(); // 5
 getchar();
 return 0;
}

上面代碼中定義了一個(gè)類Person,顯式的定義了拷貝構(gòu)造函數(shù)和賦值運(yùn)算符。然后定義了兩個(gè)函數(shù):f,以值的方式參傳入Person對(duì)象;f1,以值的方式返回Person對(duì)象。在main中模擬了5中場(chǎng)景,測(cè)試調(diào)用的是拷貝構(gòu)造函數(shù)還是賦值運(yùn)算符。執(zhí)行結(jié)果如下:

分析如下:

  1. 這是雖然使用了"=",但是實(shí)際上使用對(duì)象p來創(chuàng)建一個(gè)新的對(duì)象p1。也就是產(chǎn)生了新的對(duì)象,所以調(diào)用的是拷貝構(gòu)造函數(shù)。
  2. 首先聲明一個(gè)對(duì)象p2,然后使用賦值運(yùn)算符"=",將p的值復(fù)制給p2,顯然是調(diào)用賦值運(yùn)算符,為一個(gè)已經(jīng)存在的對(duì)象賦值 。
  3. 以值傳遞的方式將對(duì)象p2傳入函數(shù)f內(nèi),調(diào)用拷貝構(gòu)造函數(shù)構(gòu)建一個(gè)函數(shù)f可用的實(shí)參。
  4. 這條語句拷貝構(gòu)造函數(shù)和賦值運(yùn)算符都調(diào)用了。函數(shù)f1以值的方式返回一個(gè)Person對(duì)象,在返回時(shí)會(huì)調(diào)用拷貝構(gòu)造函數(shù)創(chuàng)建一個(gè)臨時(shí)對(duì)象tmp作為返回值;返回后調(diào)用賦值運(yùn)算符將臨時(shí)對(duì)象tmp賦值給p2.
  5. 按照4的解釋,應(yīng)該是首先調(diào)用拷貝構(gòu)造函數(shù)創(chuàng)建臨時(shí)對(duì)象;然后再調(diào)用拷貝構(gòu)造函數(shù)使用剛才創(chuàng)建的臨時(shí)對(duì)象創(chuàng)建新的對(duì)象p3,也就是會(huì)調(diào)用兩次拷貝構(gòu)造函數(shù)。不過,編譯器也沒有那么傻,應(yīng)該是直接調(diào)用拷貝構(gòu)造函數(shù)使用返回值創(chuàng)建了對(duì)象p3。

深拷貝、淺拷貝

說到拷貝構(gòu)造函數(shù),就不得不提深拷貝和淺拷貝。通常,默認(rèn)生成的拷貝構(gòu)造函數(shù)和賦值運(yùn)算符,只是簡單的進(jìn)行值的復(fù)制。例如:上面的Person類,字段只有int和string兩種類型,這在拷貝或者賦值時(shí)進(jìn)行值復(fù)制創(chuàng)建的出來的對(duì)象和源對(duì)象也是沒有任何關(guān)聯(lián),對(duì)源對(duì)象的任何操作都不會(huì)影響到拷貝出來的對(duì)象。反之,假如Person有一個(gè)對(duì)象為int *,這時(shí)在拷貝時(shí)還只是進(jìn)行值復(fù)制,那么創(chuàng)建出來的Person對(duì)象的int *的值就和源對(duì)象的int *指向的是同一個(gè)位置。任何一個(gè)對(duì)象對(duì)該值的修改都會(huì)影響到另一個(gè)對(duì)象,這種情況就是淺拷貝。

深拷貝和淺拷貝主要是針對(duì)類中的指針和動(dòng)態(tài)分配的空間來說的,因?yàn)閷?duì)于指針只是簡單的值復(fù)制并不能分割開兩個(gè)對(duì)象的關(guān)聯(lián),任何一個(gè)對(duì)象對(duì)該指針的操作都會(huì)影響到另一個(gè)對(duì)象。這時(shí)候就需要提供自定義的深拷貝的拷貝構(gòu)造函數(shù),消除這種影響。通常的原則是:

  • 含有指針類型的成員或者有動(dòng)態(tài)分配內(nèi)存的成員都應(yīng)該提供自定義的拷貝構(gòu)造函數(shù)
  • 在提供拷貝構(gòu)造函數(shù)的同時(shí),還應(yīng)該考慮實(shí)現(xiàn)自定義的賦值運(yùn)算符

對(duì)于拷貝構(gòu)造函數(shù)的實(shí)現(xiàn)要確保以下幾點(diǎn):

  • 對(duì)于值類型的成員進(jìn)行值復(fù)制
  • 對(duì)于指針和動(dòng)態(tài)分配的空間,在拷貝中應(yīng)重新分配分配空間
  • 對(duì)于基類,要調(diào)用基類合適的拷貝方法,完成基類的拷貝

總結(jié)

  • 拷貝構(gòu)造函數(shù)和賦值運(yùn)算符的行為比較相似,卻產(chǎn)生不同的結(jié)果;拷貝構(gòu)造函數(shù)使用已有的對(duì)象創(chuàng)建一個(gè)新的對(duì)象,賦值運(yùn)算符是將一個(gè)對(duì)象的值復(fù)制給另一個(gè)已存在的對(duì)象。區(qū)分是調(diào)用拷貝構(gòu)造函數(shù)還是賦值運(yùn)算符,主要是否有新的對(duì)象產(chǎn)生。
  • 關(guān)于深拷貝和淺拷貝。當(dāng)類有指針成員或有動(dòng)態(tài)分配空間,都應(yīng)實(shí)現(xiàn)自定義的拷貝構(gòu)造函數(shù)。提供了拷貝構(gòu)造函數(shù),最后也實(shí)現(xiàn)賦值運(yùn)算符。

以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,同時(shí)也希望多多支持腳本之家!

相關(guān)文章

  • Qt基礎(chǔ)開發(fā)之Qt多線程類QThread與Qt定時(shí)器類QTimer的詳細(xì)方法與實(shí)例

    Qt基礎(chǔ)開發(fā)之Qt多線程類QThread與Qt定時(shí)器類QTimer的詳細(xì)方法與實(shí)例

    這篇文章主要介紹了Qt基礎(chǔ)開發(fā)之Qt多線程類QThread與Qt定時(shí)器類QTimer的詳細(xì)方法與實(shí)例,需要的朋友可以參考下
    2020-03-03
  • C++中std::is_object的具體使用

    C++中std::is_object的具體使用

    std::is_object是一種C++類型特性,其用途是判斷一個(gè)類型是否是一個(gè)對(duì)象類型,本文主要介紹了C++中std::is_object的具體使用,感興趣的可以了解一下
    2024-01-01
  • 詳解C++ cin.getline函數(shù)

    詳解C++ cin.getline函數(shù)

    這篇文章主要介紹了C++ cin.getline函數(shù)的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)C++,感興趣的朋友可以了解下
    2020-09-09
  • Qt編寫地圖綜合應(yīng)用之繪制雨量分布

    Qt編寫地圖綜合應(yīng)用之繪制雨量分布

    雨量分布圖是在區(qū)域地圖基礎(chǔ)上,針對(duì)區(qū)域中的每個(gè)最小單位區(qū)域比如縣城點(diǎn)位不同顏色顯示。本文將詳細(xì)為大家介紹如何通過QT編寫繪制雨量分布,感興趣的小伙伴可以了解一下
    2021-12-12
  • C語言中關(guān)于庫函數(shù) qsort 快排的用法

    C語言中關(guān)于庫函數(shù) qsort 快排的用法

    快速排序Qsort是所有學(xué)習(xí)算法和數(shù)據(jù)結(jié)構(gòu)最基礎(chǔ)的一個(gè)部分,也是考試題和面試的一個(gè)小重點(diǎn)。本片文章帶你了解Qsort的詳細(xì)用法規(guī)則
    2021-09-09
  • C++實(shí)現(xiàn)循環(huán)隊(duì)列和鏈?zhǔn)疥?duì)列的示例

    C++實(shí)現(xiàn)循環(huán)隊(duì)列和鏈?zhǔn)疥?duì)列的示例

    下面小編就為大家分享一篇C++實(shí)現(xiàn)循環(huán)隊(duì)列和鏈?zhǔn)疥?duì)列的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • OpenCV圖像旋轉(zhuǎn)Rotate的詳細(xì)介紹

    OpenCV圖像旋轉(zhuǎn)Rotate的詳細(xì)介紹

    這篇文章主要介紹了OpenCV圖像旋轉(zhuǎn)Rotate,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • C?語言中布爾值的用法實(shí)戰(zhàn)案例

    C?語言中布爾值的用法實(shí)戰(zhàn)案例

    這篇文章主要為大家介紹了C語言中布爾值的用法實(shí)戰(zhàn)案例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • 用C語言模仿Python函數(shù)的一種簡單實(shí)現(xiàn)方法

    用C語言模仿Python函數(shù)的一種簡單實(shí)現(xiàn)方法

    這篇文章主要介紹了用C語言模仿Python函數(shù)的一種簡單實(shí)現(xiàn)方法,需要的朋友可以參考下
    2017-05-05
  • Qt實(shí)現(xiàn)簡易計(jì)時(shí)器的示例代碼

    Qt實(shí)現(xiàn)簡易計(jì)時(shí)器的示例代碼

    計(jì)時(shí)器實(shí)現(xiàn)四個(gè)功能:開始計(jì)時(shí)、停止計(jì)時(shí)、暫停計(jì)時(shí)以及打點(diǎn)。當(dāng)點(diǎn)擊暫停時(shí),開始按鈕和停止按鈕無法點(diǎn)擊。當(dāng)點(diǎn)擊停止時(shí),開始按鈕和暫停按鈕無法點(diǎn)擊,此時(shí)停止按鈕變?yōu)榍辶?。本文將用Qt實(shí)現(xiàn)這樣的一個(gè)計(jì)時(shí)器,需要的可以參考一下
    2022-06-06

最新評(píng)論

尉氏县| 中山市| 元谋县| 临江市| 嵊州市| 昌图县| 广汉市| 桑日县| 临安市| 宝鸡市| 永安市| 大名县| 双城市| 林甸县| 中阳县| 元阳县| 循化| 奉化市| 武隆县| 屯门区| 泰安市| 榕江县| 湄潭县| 孟连| 大英县| 枝江市| 韶山市| 德州市| 如皋市| 航空| 和林格尔县| 香河县| 刚察县| 三台县| 静安区| 通海县| 平度市| 芦山县| 哈尔滨市| 吴旗县| 怀来县|