利用類定義一個指針會調用默認構造函數嗎_C++的拷貝構造函數

拷貝構造函數是一種特殊的構造函數,它在創建對象時,是使用同一類中之前創建的對象來初始化新創建的對象。拷貝構造函數通常用于:

  • 通過使用另一個同類型的對象來初始化新創建的對象。

  • 復制對象把它作為參數傳遞給函數。

  • 復制對象,并從函數返回這個對象。

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

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

上面的定義的類Person顯式的刪除了拷貝構造函數和賦值運算符,在需要調用拷貝構造函數或者賦值運算符的地方,會提示_無法調用該函數,它是已刪除的函數_。
還有一點需要注意的是,拷貝構造函數必須以引用的方式傳遞參數。這是因為,在值傳遞的方式傳遞給一個函數的時候,會調用拷貝構造函數生成函數的實參。如果拷貝構造函數的參數仍然是以值的方式,就會無限循環的調用下去,直到函數的棧溢出。

  • 何時調用

拷貝構造函數和賦值運算符的行為比較相似,都是將一個對象的值復制給另一個對象;但是其結果卻有些不同,拷貝構造函數使用傳入對象的值生成一個新的對象的實例,而賦值運算符是將對象的值復制給一個已經存在的實例。這種區別從兩者的名字也可以很輕易的分辨出來,拷貝構造函數也是一種構造函數,那么它的功能就是創建一個新的對象實例;賦值運算符是執行某種運算,將一個對象的值復制給另一個對象(已經存在的)。調用的是拷貝構造函數還是賦值運算符,主要是看是否有新的對象實例產生。如果產生了新的對象實例,那調用的就是拷貝構造函數;如果沒有,那就是對已有的對象賦值,調用的是賦值運算符

調用拷貝構造函數主要有以下場景:

  • 對象作為函數的參數,以值傳遞的方式傳給函數。 

  • 對象作為函數的返回值,以值的方式從函數返回

  • 使用一個對象給另一個對象初始化

代碼如下:

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;}

上面代碼中定義了一個類Person,顯式的定義了拷貝構造函數和賦值運算符。然后定義了兩個函數:f,以值的方式參傳入Person對象;f1,以值的方式返回Person對象。在main中模擬了5中場景,測試調用的是拷貝構造函數還是賦值運算符。執行結果如下:61c697a746e07f15e3cded930d979057.png

分析如下:

  • 這是雖然使用了"=",但是實際上使用對象p來創建一個新的對象p1。也就是產生了新的對象,所以調用的是拷貝構造函數。

  • 首先聲明一個對象p2,然后使用賦值運算符"=",將p的值復制給p2,顯然是調用賦值運算符,為一個已經存在的對象賦值 。

  • 以值傳遞的方式將對象p2傳入函數f內,調用拷貝構造函數構建一個函數f可用的實參。

  • 這條語句拷貝構造函數和賦值運算符都調用了。函數f1以值的方式返回一個Person對象,在返回時會調用拷貝構造函數創建一個臨時對象tmp作為返回值;返回后調用賦值運算符將臨時對象tmp賦值給p2.

  • 按照4的解釋,應該是首先調用拷貝構造函數創建臨時對象;然后再調用拷貝構造函數使用剛才創建的臨時對象創建新的對象p3,也就是會調用兩次拷貝構造函數。不過,編譯器也沒有那么傻,應該是直接調用拷貝構造函數使用返回值創建了對象p3。

  • 深拷貝、淺拷貝

說到拷貝構造函數,就不得不提深拷貝和淺拷貝。通常,默認生成的拷貝構造函數和賦值運算符,只是簡單的進行值的復制。例如:上面的Person類,字段只有intstring兩種類型,這在拷貝或者賦值時進行值復制創建的出來的對象和源對象也是沒有任何關聯,對源對象的任何操作都不會影響到拷貝出來的對象。反之,假如Person有一個對象為int *,這時在拷貝時還只是進行值復制,那么創建出來的Person對象的int *的值就和源對象的int *指向的是同一個位置。任何一個對象對該值的修改都會影響到另一個對象,這種情況就是淺拷貝。

深拷貝和淺拷貝主要是針對類中的指針動態分配的空間來說的,因為對于指針只是簡單的值復制并不能分割開兩個對象的關聯,任何一個對象對該指針的操作都會影響到另一個對象。這時候就需要提供自定義的深拷貝的拷貝構造函數,消除這種影響。通常的原則是:

  • 含有指針類型的成員或者有動態分配內存的成員都應該提供自定義的拷貝構造函數

  • 在提供拷貝構造函數的同時,還應該考慮實現自定義的賦值運算符

對于拷貝構造函數的實現要確保以下幾點:

  • 對于值類型的成員進行值復制

  • 對于指針和動態分配的空間,在拷貝中應重新分配分配空間

  • 對于基類,要調用基類合適的拷貝方法,完成基類的拷貝

d9bc74cdcfd6c9e149022885b4eeb833.png

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/537378.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/537378.shtml
英文地址,請注明出處:http://en.pswp.cn/news/537378.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

開發應用層的需要了解 framework層嗎?---不需要!!!!

寫于2015年12月3日 不同的android版本&#xff0c;不同的framework實現&#xff0c;framework有近2億行代碼&#xff0c;版本越高&#xff0c;代碼行數越大&#xff0c;這個過程是很痛苦的。所以不要去學習和閱讀framework的源代碼。 閱讀它的源代碼&#xff0c;還不如去學英…

51CTO會員開通成功!開森!

很好&#xff0c;是理想中的學習平臺&#xff0c;果斷買了&#xff01;^_^ 開森ing 轉載于:https://blog.51cto.com/13601545/2324935

一個請求多個響應_一個TCP連接到底可以發多少個HTTP請求?

曾經有這么一道面試題&#xff1a;從 URL 在瀏覽器被被輸入到頁面展現的過程中發生了什么&#xff1f;相信大多數準備過的同學都能回答出來&#xff0c;但是如果繼續問&#xff1a;收到的 HTML 如果包含幾十個圖片標簽&#xff0c;這些圖片是以什么方式、什么順序、建立了多少連…

手機定位功能為什么打開WiFi(不連接) 就會非常的準 ?如果WiFi 遷到其它地方去了呢?

Wifi定位地圖在需要定位的時候&#xff0c;一般會優先用GPS的定位結果&#xff0c;一般來說GPS最準。如果沒有GPS的定位結果的話&#xff0c;那一般就退而求其次用Wifi的定位結果。 原理是這樣的&#xff1a; 1、手機收集它能夠搜索到的Wifi的信息&#xff1b; 2、提交Wifi信…

JxBrowser概述與簡單應用

Q&#xff1a;JxBrowser是什么&#xff1f; JxBrowser是一個跨平臺的Java庫&#xff0c;允許將基于Google Chromium的Web瀏覽器組件集成到Java Swing / AWT / JavaFX應用程序中。使用JxBrowser&#xff0c;您可以將輕量級Swing / JavaFX組件嵌入到Java應用程序中&#xff0c;以…

我的達內Java培訓經歷

我當時2009年參加達內培訓是在學校里,達內與我們學校合作。當時培訓班只開了一個班,有位班主任,因為是第一屆,學生也少,不到20個,所以不是老師現場教的,看視頻學習的,視頻是錄播的。班主任負責培訓班日常管理工作,和技術答疑。培訓視頻是投影儀放。當時培訓java基礎的…

小米大數據:借助Apache Kylin打造高效、易用的一站式OLAP解決方案

如今的小米不僅是一家手機公司&#xff0c;更是一家大數據與人工智能公司。隨著小米公司各項業務的快速發展&#xff0c;數據中的商業價值也愈發突顯。而與此同時&#xff0c;各業務團隊在數據查詢、分析等方面的壓力同樣正在劇增。因此&#xff0c;為幫助公司各業務線解決這些…

舊電腦升級Win11

2014年的聯想Y430P升級成功 升級很簡單 第一步&#xff1a;下載win11系統安裝包&#xff0c;下載地址&#xff1a;系統之家 - Win11系統 第二步&#xff1a;下載KMS激活工具&#xff0c;下載地址&#xff1a;https://www.jb51.net/softs/668522.htmlhttps://www.jb51.net/sof…

進程池的用法

apply() 函數原型&#xff1a; apply(func[, args()[, kwds{}]]) 該函數用于傳遞不定參數&#xff0c;主進程會被阻塞直到函數執行結束&#xff08;不建議使用&#xff0c;并且3.x以后不在出現&#xff09;。 apply_async() 函數原型&#xff1a; apply_async(func[, args()[, …

巧刪無法刪除的文件

遇到無法刪除的文件&#xff0c;電腦上沒有文件粉碎工具&#xff0c;或文件粉碎工具也刪不掉&#xff0c;怎么辦&#xff1f; 很簡單&#xff1a; 把文件的后綴名改掉&#xff0c;比如改成doc&#xff0c;重啟電腦&#xff0c;再刪除

萬用表測線路斷點位置_如何測出電線電纜斷點在哪?來看看常見的7種方法

實際工程維護檢修中&#xff0c;對于維修人員來說最怕的莫過于碰到電線電纜中間斷了找不出斷點在什么地方。雖然我們弱電工程實際維修的時候&#xff0c;碰到線纜問題會直接想辦法換線或者重新敷設&#xff0c;但是我們今天討論技術上有哪些方法可以測出線纜的斷點&#xff01;…

12.04個人博客

地點&#xff1a;自習室 事件&#xff1a;召開小組會議&#xff0c;進項任務分配轉載于:https://www.cnblogs.com/qingjia/p/10145891.html

你真的會用OneNote嗎?

你真的會用OneNote嗎&#xff1f;_程序媛一枚-CSDN博客前言特色功能圖片轉文字TAB制表符新建表格表格嵌套自動編號保存微信文稿樹形目錄基本功能總結前言使用OneNote做筆記已經有一年多的時間了&#xff0c;從最開始的抵觸&#xff0c;到現在的習慣&#xff0c;心態的轉變主要是…

樂學python_鐵樂學python_day01-作業

第一題&#xff1a;使用while循環輸入 1 2 3 4 5 6 8 9 10# 使用while循環輸入 1 2 3 4 5 6 8 9 10count 0while (True) :count count 1#判斷當count等于7的時候&#xff0c;返回循環最初&#xff0c;不執行下面的打印等語句if count 7:continueprint (count)#判斷當count等…

大道至簡: 拉新、促活和留存

互聯網運營中的拉新、促活和留存思維&#xff0c;從來不局限于互聯網產品里&#xff0c;在傳統行業里也是通用的&#xff0c;比如一家理發店的經營也是如此。 互聯網運營中的拉新、促活和留存思維&#xff0c;從來不局限于互聯網產品里&#xff0c;在傳統行業里也是通用的。比如…

python3的pyqt5 qtablewidget按數據大小排列_InnoDB為什么要選擇B+樹來存儲數據?

關于InnoDB索引&#xff0c;我們可能知道InnDB索引是用B樹實現的&#xff0c;而B樹就是一種能優化查詢速度的數據結構。但我們又沒想過這樣一個問題&#xff0c;能優化查詢速度的數據結構有很多&#xff0c;為什么InnoDB要采用B樹&#xff1f;常見優化查詢速度數據結構哈希表哈…

數據倉如何支撐應用?

數據倉支撐應用&#xff0c;主要有以下步驟&#xff1a; 1.應用部門&#xff1a;在“寧波市公共數據目錄平臺”按需申請省市共享數據&#xff0c;申請的表審批通過后&#xff0c;提交《審批通過的表清單》給大數據中心&#xff1b; 2.大數據中心&#xff1a;比對《審批通過的…

辛苦倆月總結的面試題,掌握它懟翻面試官不是夢~

小編經過一個多月的不懈努力&#xff0c;給大家總結了一份面試方面的題目。這份面試題涉及高并發、分布式、高可用相關知識點&#xff0c;在此分享給大家&#xff0c;希望大家能拿到一份理想的 Offer&#xff01;因為是筆試題目&#xff0c;大家可以先做。如果需要查看答案&…

python坐標轉化極坐標_python 坐標系

廣告關閉提供包括云服務器&#xff0c;云數據庫在內的50款云計算產品。打造一站式的云產品試用服務&#xff0c;助力開發者和企業零門檻上云。寫在前面的話01 今天資源君帶大家學習一下python的可視化&#xff0c;何謂可視化呢&#xff1f; 我們常常聽說python的數據分析&#…