【C++】——類和對象(中)——默認成員函數

一、類的默認成員函數

默認成員函數就是用戶沒有顯示實現,不過編譯器會自動生成的成員函數,稱為默認成員函數。一個類默認成員函數一共有6個,在我們不寫的情況下,編譯器就會自動生成這6個成員函數,不過我們重點要學習的是前面四個,后面兩個了解即可。還有就是在C++11后還增加了兩個默認成員函數,移動構造和移動賦值,這個我們后續講解C++11的時候也會進行講解。

默認成員函數比較復雜,我們主要從下面兩個方面進行學習理解:

1、我們不寫的時候,編譯器默認生成的函數行為是什么?是否可以滿足我們的需求?

2、編譯器默認生成的函數不滿足我們的需求的時候,那么我們就要自己去實現,那么要如何進行? ? ? ?實現呢?

下面我們就從幾種默認成員函數來入手:

二、構造函數

構造函數是一種特殊的成員函數,它的功能類似我們在前面實現鏈表、棧、隊列等的數據結構的初始化函數一樣,其是用來實現實例化對象初始化始化對象。還要注意的是,雖然名字叫做構造函數,但是其不會去開空間,其是局部變量進行初始化的。

下面是構造函數要注意的點:
1、構造函數的函數名和類的名字一樣

2、構造函數無返回值,而且我們在定義和聲明的時候連void都不需要寫

3、對象實例化的時候系統就會自動調用構造函數

4、構造函數可以重載

下面我們通過代碼來深入學習一下:

可以看到我們上面沒有去調用這個構造函數,那么我們看看其運行結果是否會自動調用這個構造函數使得我們的成員變量初始化:

? ?可以看到我們的成員變量被初始化成功了。所以說我們在實例化對象的時候編譯器會自動調用我? ? ?們的構造函數。

? ?我們上面還提到了,我們的構造函數還可以重載,也就是說我們的構造函數可以不止一個,可以? ? ? 有多個,然后編譯器會根據我們傳的參數來進行判斷該調用那個:

? ? ?運行結果如下:
? ? ?我們可以看到當我們要調用的是需要進行傳參的構造函數,那么我們在實例化的時候,就需要? ? ? ? 在后面加上括號然后進行傳參。

? ? ?那么我們對于沒有參數的那個構造函數,我們在實例化對象的時候加個括號是否可以呢?

? ? ? 答案是不行滴:

? ? 可以看到編譯器直接就報錯了。

? ? ?構造函數的使用要求還有以下幾個:
5、如果類中沒有顯示定義構造函數,那么C++編譯器會自動生成一個無參的默認構造函數,一旦? ? ? ?顯示定義那么編譯器不再生成。

6、無參構造函數、全缺省構造函數、我們不寫構造時編譯器默認生成構造函數這三種構造函數都? ? ? ?叫默認構造函數。但是我們前面學習函數重載的時候就知道,這三個函數就只能存在一個,不? ? ? ?可以共存。無參構造函數和全缺省構造函數雖然構造函數重載,但是不傳參調用時會有歧義。

? ? ? 可以看到錯誤信息中提示到,函數的調用不明確。

7、我們不寫構造函數,那么編譯器就會自動生成構造函數,對于內置類型成員變量的初始化是不? ? ? ? 確定的,那么具體被初始化成什么就由編譯器來確定了。對于自定義類型變量要求調用這個成? ? ? ? 員變量的默認構造函數進行初始化。如果這個成員變量沒有默認構造函數,那么編譯器就會報? ? ? ? 錯嗎,那么我們要初始化這個變量就需要用到初始化列表,初始化列表我們后續再進行講解。

? ? ?在C++中將數據類型分為內置類型和自定義類型

? ? ?內置類型:int、char、double等等

? ? ?自定義類型:我們使用class和struct等關鍵字進行定義的類型

下面我們就來看看編譯器自動生成的構造函數是如何的:

?我們可以看到我們在定義類的時候我們沒有寫構造函數的,那么我們在實例化對象的時候,我們的編譯器就會自動幫我們默認構造函數,但是其具體是初始化什么內容我們就不知道了,我們上面的代碼對成員變量的初始化就沒啥有要求了。

還有一種情況就是我們的成員變量也是一個類,然后我們的成員變量有構造函數,那么我們這個類就可以不寫構造函數了,那么其就會使用成員變量那個類的構造函數。

比如我們前面學習的數據結構中,使用棧實現隊列,那么我們的隊列類中的成員變量就是兩個棧:

可以看到兩個棧確定被初始化為了4。

要是我們的棧中的構造函數,其參數修改成需要進行傳參的函數,那么就需要用來初始化列表了,

?不過我們可以知道的是,對于大部分的類,我們都需要自己去寫構造函數,因為編譯器默認的很多情況都不能滿足需求。

三、析構函數

析構函數的功能和構造函數是相反的,有點類似于我們在實現棧的時候的Destroy函數的功能,用來完成對對象中的清理釋放工作。要注意的是其不是完成對對象的銷毀,比如局部對象是有棧幀的,函數結束的時候會銷毀棧幀,那么這個局部對象也就跟著銷毀了,所以對于局部對象我們是不要理的,其也不需要析構函數。但是C++中規定了對象在銷毀時會自動調用析構函數,用于完成資源的清理。如果對于一個類沒有資源要進行釋放的,那么理論上就不需要析構函數。

下面是析構函數使用上的一些要求:

1、析構函數名是在類名前加上字符~。

2、析構函數和構造函數一樣是無參無返回值的,而且也不需要寫void。

3、一個類中只能有一個析構函數只能有一個析構函數。若未顯示定義,那么系統就會自動生成默? ? ? ?認的析構函數。

4、對象生命周期結束時,系統就會自動調用析構函數。

5、一個局部域有多個實例化對象的時候,后定義的會先進行析構。

下面我們通過代碼來感受一下:

?

可以看到st1和st2都已經按照我們給的參數進行初始化了,然后我們繼續往下運行:

?可以看到我們是先將st2的銷毀了,然后再對st1進行銷毀的。

6、和構造函數一樣,我們不寫的話,那么編譯器就會自動去生成這個函數,其不對內置類型的成? ? ? ?員變量操作,自定義類的成員變量就會進行處理。

7、還需要注意的是,我們顯示寫析構的時候,對于自定義類型的成員其也會調用它的析構函數,? ? ? ?不會受到在這個類中寫的析構函數的影響。也就是說自定義類型不論什么情況下都會去自動調? ? ? ?用析構函數。

我們前面學習數據結構的時候,我們寫了道使用棧實現隊列的題目,下面我們通過這個例子來看看,我們可以在析構函數中打印一些東西來看這個函數被調用了多少次:

首先就是,我們知道的是,我們的隊列自定義類型中,其有兩個成員變量,編譯器會其調用這個成員變量的析構函數,那么就會其棧類中調用,那么我們一共兩個棧,所以其調用兩次。

?還有就是我們要是沒有去向操作系統申請空間,那么我們的析構函數其實是可以不寫的,直接使用編譯器默認生成的析構函數即可,所以當我們需要進行空間申請的時候,一定要寫析構函數,不然就會造成內存泄漏。

四、拷貝構造函數

如果一個構造函數的第一個參數是自身類類型的引用,而且任何地方的參數都有默認值,那么此函數就叫做拷貝構造函數。

下面是拷貝構造函數使用的時候的特點:

1、拷貝構造函數是構造函數的一個重載。

2、拷貝構造函數的第一個參數必須是類類型對象的引用,使用傳值方式的話編譯器會直接報錯,? ? ? ?這是因為在語法邏輯上會導致無窮遞歸調用。拷貝構造函數也可以有多個參數,但是第一個參? ? ? ?數一定要保證是類類型對象的引用,而且后面的參數一定要有缺省值。

我們上面的代碼,將a1作為參數傳給a2的拷貝構造函數,那么a2的值就會和a1的一樣了。

還有就是我們的拷貝構造函數的參數部分可以加一個const關鍵字,因為我們不想被拷貝的對象被改變,還有就是對于被const關鍵字修飾的對象我們也可將其拷貝。

?那么為啥不可以傳值呢?這是因為傳值的話,其會導致無窮遞歸調用拷貝構造函數,那是為啥會導致這個問題呢?

這是因為我們傳值的時候,是一種淺拷貝,那么會創建一個臨時變量先將參數的進行拷貝,但是我們在創建這個臨時變量的時候,因為其也是類類型,那么其進行拷貝那么就會去調用拷貝構造函數,那么就造成了無窮遞歸。

引用傳參的話,那么其是使用的實參的別名,那么在傳參的過程中是不會產生拷貝的,其實際上就直接對這個傳入的參數的內容進行拷貝了,所以不存在淺拷貝,就直接進入到函數中了,所以不會導致無窮遞歸。

3、C++中規定了自定義類型對象進行拷貝的行為必須調用拷貝構造,所以自定義類型傳參和傳值? ? ? ?都會調用拷貝構造函數來完成。

4、要是未顯示定義拷貝構造函數,那么編譯器就會自動生成拷貝構造函數,那么自動生成的拷貝? ? ? ? 構造函數對內置類型的成員變量會完成值拷貝,即一個字節一個字節的拷貝,和我們前面學習? ? ? ? C語言的時候對字符串進行拷貝一樣,對于自定義類型的成員變量那么就會調用其拷貝構造函? ? ? ? 數。

不過對于一些比較復雜的成員變量,要是使用編譯器自動生成的拷貝構造函數,會造成不好的效果,比如我們的棧成員變量:

?

?

可以看到我們的程序就直接運行不起來了,這是因為st1初始化的時候,_a會被分配一塊空間,但是st2就是st1的淺拷貝,但是此時st2中的_arr和st1中的_arr使用的是一塊空間了。

所以這種情況下我們一定要自己去寫拷貝構造函數來實現深拷貝。

5、像我們上面的Date類中,其成員變量全是內置類型而且沒有什么指向資源,那么編譯器自動生? ? ? ? 成的拷貝構造函數就可以完成了,所以我們可以不去寫,但是像Stack類這樣的,雖然其也是? ? ? ? ? 內置類型,但是_arr其指向了資源,編譯器自動生成的拷貝構造函數完成的是值拷貝,達不到? ? ? ? 我們的需求,所以我們要自己實現一個深拷貝。還有就是很前面的使用棧實現隊列中的隊列類? ? ? ? 也是一樣,其成員變量的棧的類其有顯示的拷貝構造函數,那么我們的隊列類中可以不寫,其? ? ? ? 會去調用棧的拷貝構造函數。

? ? ? 下面有個技巧:

? ? ? ?如果一個類顯示的實現了析構函數,而且釋放了資源,那么其就需要顯示的寫拷貝構造。

6、傳值返回會產生一個臨時對象的拷貝構造,傳值引用返回,返回的是返回對象的別名,那么就沒產生拷貝。那么如果返回對象是一個當前函數的局部域的局部對象,那么函數結束就銷毀了,那么使用引用返回是有問題的,此時的引用就是野引用了。

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

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

相關文章

MATLAB知識點總結

1.將A圖與B圖相同范圍內歸一化顯示在同一個figure上: figure, plot(A(150:450,500)/max(A(150:450,500))) hold on plot(D(150:450,500)/max(D(150:450,500)),‘R’) 將兩幅圖像的一定范圍顯示在同一圖像上。 figure,plot(A(350,100:450)) hold on plot(G(350,100:4…

易天光通信10G SFP+ 1550nm 120KM 雙纖光模塊:遠距離傳輸的實力擔當

目錄 前言 一、10G SFP雙纖光模塊概述 二、易天10G SFP 120KM 雙纖光模塊核心優勢與應用 核心優勢: 主要關鍵應用如下: 三、易天10G SFP 120KM 雙纖光模塊客戶優勢 總結 關于易天 前言 在構建高效穩定的網絡架構時,10G SFP 光模塊 12…

【深度學習】神經網絡 批量標準化-part6

九、批量標準化是一種廣泛使用的神經網絡正則化技術,對每一層的輸入進行標準化,進行縮放和平移,目的是加速訓練,提高模型穩定性和泛化能力,通常在全連接層或是卷積層之和,激活函數之前使用核心思想對每一批…

【數據可視化-67】基于pyecharts的航空安全深度剖析:墜毀航班數據集可視化分析

🧑 博主簡介:曾任某智慧城市類企業算法總監,目前在美國市場的物流公司從事高級算法工程師一職,深耕人工智能領域,精通python數據挖掘、可視化、機器學習等,發表過AI相關的專利并多次在AI類比賽中獲獎。CSDN…

【科研繪圖系列】R語言繪制分組箱線圖

文章目錄 介紹 加載R包 數據下載 導入數據 畫圖1 畫圖2 合并圖 系統信息 參考 介紹 【科研繪圖系列】R語言繪制分組箱線圖 加載R包 library(ggplot2) library(patchwork)rm(list = ls()) options(stringsAsFactors = F)

基于Android的旅游計劃App

項目介紹系統打開進入登錄頁面,如果沒有注冊過賬號,點擊注冊按鈕輸入賬號、密碼、郵箱即可注冊,注冊后可登錄進入系統,系統分為首頁、預訂、我的三大模塊,下面具體詳細說說三大模塊功能說明。1.首頁顯示旅游備忘或旅游…

【LeetCode 2163. 刪除元素后和的最小差值】解析

目錄LeetCode中國站原文原始題目題目描述示例 1:示例 2:提示:講解分割線的藝術:前后綴分解與優先隊列的完美邂逅第一部分:算法思想 —— “分割線”與前后綴分解1. 想象一條看不見的“分割線”2. 前后綴分解&#xff1…

控制鼠標和鍵盤

控制鼠標和鍵盤的Python庫Python中有多個庫可以用于控制鼠標和鍵盤,常用的包括pyautogui、pynput、keyboard和mouse等。這些庫提供了模擬用戶輸入的功能,適用于自動化測試、GUI操作等場景。使用pyautogui控制鼠標pyautogui是一個跨平臺的庫,支…

基于按鍵開源MultiButton框架深入理解代碼框架(二)(指針的深入理解與應用)

文章目錄2、針對該開源框架理解3、分析代碼3.1 再談指針、數組、數組指針3.2 繼續分析源碼2、針對該開源框架理解 在編寫按鍵模塊的框架中,一定要先梳理按鍵相關的結構體、枚舉等變量。這些數據是判斷按鍵按下、狀態跳轉、以及綁定按鍵事件的核心。 這一部分定義是…

web前端渡一大師課 CSS屬性計算過程

你是否了解CSS 的屬性計算過程呢? <body> <h1>這是一個h1標題</h1> </body> 目前我們沒有設置改h1的任何樣式,但是卻能看到改h1有一定的默認樣式,例如有默認的字體大小,默認的顏色 那么問題來了,我們這個h1元素上面除了有默認字體大小,默認顏色等…

Redis高頻面試題:利用I/O多路復用實現高并發

Redis 通過 I/O 多路復用&#xff08;I/O Multiplexing&#xff09;技術實現高并發&#xff0c;這是其單線程模型能夠高效處理大量客戶端連接的關鍵。以下是通俗易懂的解釋&#xff0c;結合 Redis 的工作原理&#xff0c;詳細說明其實現過程。 1. 什么是 I/O 多路復用&#xff…

爬蟲小知識(二)網頁進行交互

一、提交信息到網頁 1、模塊核心邏輯 “提交信息到網頁” 是網絡交互關鍵環節&#xff0c;借助 requests 庫的 post() 函數&#xff0c;能模擬瀏覽器向網頁發數據&#xff08;如表單、文件 &#xff09;&#xff0c;實現信息上傳&#xff0c;讓我們能與網頁背后的服務器 “溝通…

WPF學習(五)

文章目錄一、FileStream和StreamWriter理解1.1、具體關系解析1.2、類比理解1.3、總結1.4、示例代碼1.5、 WriteLine()和 Write&#xff08;&#xff09;的區別1.6、 StreamWriter.Close的作用二、一、FileStream和StreamWriter理解 在 C# 中&#xff0c;StreamWriter 和 FileS…

ctf.show-web習題-web2-最簡單的sql注入-flag獲取詳解、總結

解題思路打開靶場既然提示是最簡單的sql注入了&#xff0c;那么直接嘗試永真登錄1 or 11#這里閉合就是簡單的單引號可以看到沒登錄成功&#xff0c;但是有回顯&#xff1a;歡迎你&#xff0c;ctfshowsql注入最喜歡的就是回顯了&#xff01;這題的思路就是靠這個回顯&#xff0c…

upload-labs 靶場通關(1-20)

目錄 Pass-01(JS 繞過) Pass-02(文件類型驗證) Pass-03(黑名單驗證) Pass-04(黑名單驗證.htaccess) Pass-05(大小寫繞過) Pass-06(末尾空格) Pass-07(增加一個.) Pass-08(增加一個::$DATA) Pass-09&#xff08;代碼不嚴謹&#xff09; Pass-10&#xff08;PPHPHP&am…

[附源碼+數據庫+畢業論文]基于Spring+MyBatis+MySQL+Maven+vue實現的酒店預訂管理系統,推薦!

摘 要 使用舊方法對酒店預訂信息進行系統化管理已經不再讓人們信賴了&#xff0c;把現在的網絡信息技術運用在酒店預訂信息的管理上面可以解決許多信息管理上面的難題&#xff0c;比如處理數據時間很長&#xff0c;數據存在錯誤不能及時糾正等問題。 這次開發的酒店預訂管理系…

LSTM入門案例(時間序列預測)| pytorch實現(可復現)

需求 假如我有一個時間序列&#xff0c;例如是前113天的價格數據&#xff08;訓練集&#xff09;&#xff0c;然后我希望借此預測后30天的數據&#xff08;測試集&#xff09;&#xff0c;實際上這143天的價格數據都已經有了。這里為了簡單&#xff0c;每一天的數據只有一個價…

Axure RP 10 預覽顯示“無標題文檔”的空白問題探索【護航版】

1. 安裝情況 官網 Axure RP 10&#xff1a;Download Axure RP 10 - Axure &#xff08;PS&#xff1a;11都出了&#xff09; 版本&#xff1a;10.0.0.3924 激活碼&#xff1a;49bb9513c40444b9bcc3ce49a7a022f9 &#xff08;10/11都可以用&#xff0c;但只嘗試了10&#xff…

基于SpringBoot+Vue的汽車租賃系統(協同過濾算法、騰訊地圖API、支付寶沙盒支付、WebsSocket實時聊天、ECharts圖形化分析)

系統亮點&#xff1a;協同過濾算法、騰訊地圖API、支付寶沙盒支付、WebsSocket實時聊天、ECharts圖形化分析&#xff1b;01系統開發工具與環境搭建—前后端分離架構項目架構&#xff1a;B/S架構運行環境&#xff1a;win10/win11、jdk17前端&#xff1a;技術&#xff1a;框架Vue…

數據結構入門:像整理收納一樣簡單!

在我們生活中&#xff0c;經常會面對這樣的問題&#xff1a; “我要怎么整理我的衣柜&#xff1f;” “電腦里照片太多了&#xff0c;怎么歸類才方便查找&#xff1f;” 其實&#xff0c;程序員也有類似的煩惱。他們不整理衣柜&#xff0c;而是“整理數據”。而這門關于如何“收…