c++------類和對象(下)包含了this指針、構造函數、析構函數、拷貝構造等

文章目錄

  • 前言
  • 一、this指針
    • 1.1、this指針的引出
    • 1.2、 this指針的特性
  • 二、類的默認的六個構造函數
    • 2.1、構造函數簡述
    • 2.2構造函數
  • 三、析構函數
    • 3.1、析構函數引出
    • 3.2、特點:
  • 四、拷貝構造
    • 4.1、引入
    • 4.2、特征:
    • 4.3、默認拷貝構造函數
  • 總結


前言

在本節中,我將給大家介紹我們在學習C++中經常要用到的,this指針、類的六個默認成員函數、運算符重載等相關知識.

下面我會結合一個簡單的類----日期類來介紹

后面需要時會補充相應的成員函數

class Date
{
public:void Display()//打印類對象中的內容{cout << _year << "-" << _month << "-" << _day << endl;}void SetDate(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year; // 年int _month; // 月int _day; // 日
};

一、this指針

1.1、this指針的引出

int main(){Date d1, d2;d1.SetDate(2024,5,1);d2.SetDate(2024,6,1);d1.Display();d2.Display();return 0;}

當執行上述代碼時,它的輸出結果為:
在這里插入圖片描述
下面的匯編不了解的,可以搜一下棧幀的創建和銷毀,對今后的學習幫助很大
在這里插入圖片描述

通過匯編我們可以看到,兩次調用的SetDat函數地址相同(調用同一函數)

對于上述類,有這樣的一個問題:
Date類中有SetDate與Display兩個成員函數,函數體中沒有關于不同對象的區分,那當d1調用SetDate函數時,該函數是如何知道應該設置s1對象,而不是設置d2對象呢?

C++中通過引入this指針解決該問題,即:C++編譯器給每個“非靜態的成員函數“增加了一個隱藏的指針參數,讓該指針指向當前對象(函數運行時調用該函數的對象),在函數體中所有成員變量的操作,都是通過該指針去訪問。只不過所有的操作對用戶是透明的,即用戶不需要來傳遞,編譯器自動完成。

1.2、 this指針的特性

  1. this指針只能在“成員函數”的內部使用
  2. this指針本質上其實是一個成員函數的形參,是對象調用成員函數時,將對象地址作為實參傳遞給this形參。
  3. this指針是成員函數第一個隱含的指針形參,不需要用戶
    傳遞.

將調用成員函數展開:
在這里插入圖片描述

下面我們來證明一下this指針,本質上就是對象的地址:

為了更清晰的展示,我會簡化用不到的代碼

class Date
{
public:void Print_this(){cout << this << endl;//打印this指針}
private:int _year; // 年int _month; // 月int _day; // 日
};
int main()
{Date d1, d2;d1.Print_this();//cout << &d1 << endl;//如果和我們說的一樣,那么打印結果應該兩兩相同d2.Print_this();cout << &d2 << endl;return 0;
}

結果:
在這里插入圖片描述
可以看到this本質就是對象的地址。這就是隱藏的this指針,當然我們可以像學習C語言時知道一個結構體對象的地址使用“->”來進行成員變量的訪問

class Date{public:void Display(){cout <<this-> _year << "-" <<this-> _month << "-" << this->_day << endl;}private:int _year; // 年int _month; // 月int _day; // 日};

二、類的默認的六個構造函數

在這里插入圖片描述

恩師莫怪

2.1、構造函數簡述

如果一個類中什么成員都沒有,簡稱為空類。空類中什么都沒有嗎?并不是的,任何一個類在我們不寫的情況下,編譯器都會自動生成6個默認成員函數。這些函數叫做構造函數。構造函數的任務是初始化類對象的數據成員,無論何時只要類的對象被創建,就會執行構造函數。
構造函數特點:

1.構造函數的名字和類名相同。
2.和其他函數不一樣的是,構造函數沒有返回類型。
3.類似于其他的函數,構造函數也有一個(可能為空的)參數列表和一個(可能為空的)函數體。
4.構造函數不能被聲明成const 的。

需要特別注意的是,一個類可以擁有多個參數不同的構造函數,這些構造函數之間,向普通函數之間一樣,可以構成函數重載

2.2構造函數

再貼一遍方便大家看

class Date
{
public:void Display()//打印類對象中的內容{cout << _year << "-" << _month << "-" << _day << endl;}void SetDate(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year; // 年int _month; // 月int _day; // 日
};

對于Date類,可以通過SetDate公有的方法給對象設置內容,但是如果每次創建對象都調用該方法設置信息,未免有點麻煩,那能否在對象創建時,就將信息設置進去呢?我們上面說過:創建類的類型對象時由編譯器自動調構造函數,保證每個數據成員都有 一個合適的初始值,并且在對象的生命周期內只調用一次。

class Date
{
public:// 1.無參構造函數Date(){}// 2.帶參構造函數Date(int year, int month, int day)//無返回值{_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};
void TestDate()
{Date d1; // 調用無參構造函數Date d2(2024, 6, 1); // 調用帶參的構造函數,用于初始化// 注意:如果通過無參構造函數創建對象時,對象后面不用跟括號,否則就成了函數聲明// 以下代碼的函數:聲明了d3函數,該函數無參,返回一個日期類型的對象Date d3();

如果類中沒有顯式定義構造函數,則C++編譯器會自動生成一個無參的默認構造函數,一旦用戶顯式定義編譯器將不再生成。
1.證明編譯器默認生成的為無參的構造函數:

在這里插入圖片描述

可以看到,我將自己寫的構造函數屏蔽后,調用有參的構造函數是無法成功的,無參的并沒有報錯,這也說明編譯器默認生成的為無參的構造函數。
2.證明當我們顯示寫出一個構造函數,編譯器就不會在生成默認的構造函數:
在這里插入圖片描述

我將帶參的構造函數顯示定義,d1無法調用無參的默認構造函數。
無參的構造函數和全缺省的構造函數都稱為默認構造函數,并且這兩個默認構造函數不能同時存在。注意:無參構造函數、全缺省構造函數、我們沒寫編譯器默認生成的構造函數,都可以認為是默認成員函數.

默認構造函數我們一般是為了處理自定義類型的成員變量

三、析構函數

3.1、析構函數引出

前面通過構造函數的學習,我們知道一個對象時怎么來的,那一個對象又是怎么沒呢的?
析構函數:與構造函數功能相反,析構函數不是完成對象的銷毀,局部對象銷毀工作是由編譯器完成的。而對象在銷毀時會自動調用析構函數,完成類的一些資源清理工作(比如:類中定義的指針指向的空間的清理)

3.2、特點:

  1. 析構函數名是在類名前加上字符 ’~‘。
  2. 無參數無返回值。
  3. 一個類有且只有一個析構函數。若未顯式定義,系統會自動生成默認的析構函數。
  4. 對象生命周期結束時,C++編譯系統系統自動調用析構函數
![class Date
{
public:~Date(){_year = 0;_month = 0;_day = 0;} Date(int year, int month, int day){_year = year;_month = month;_day = day;}int _year;int _month;int _day;
};
int main()
{Date d2(2024, 6, 1);return 0;
}

反匯編視角:
在這里插入圖片描述

在上面的代碼中,我并沒有去顯示調用析構函數,但是在程序執行結束時,編譯器自動調用了,析構函數
這個也可以像構造函數一樣測試,大家嘗試一下

四、拷貝構造

4.1、引入

拷貝構造函數是構造函數的一種重載形式,它可以用來創建一個與已存在的對象一模一樣的新對象。對于拷貝構造,它只有單個形參,且該形參必須是對本類類型對象的引用,因為要引用,所以要加const修飾。

4.2、特征:

1.拷貝構造函數的參數若使用傳值方式編譯器直接報錯, 因為會引發無窮遞歸調用
2.若未顯式定義,編譯器會生成默認的拷貝構造函數。 默認的拷貝構造函數,對對象按 字節序完成拷貝,這種拷貝叫做淺拷貝,或者值拷貝。
3.編譯器生成的默認拷貝構造函數已經可以完成字節序的值拷貝了。

class Date
{
public:Date(int year = 1900, int month = 1, int day = 1)//全缺省{_year = year;_month = month;_day = day;}// Date(const Date d)   // 錯誤--引發無窮遞歸Date(const Date& d)   // 正確寫法_year = d._year;_month = d._month;_day = d._day;}
private:int _year;int _month;int _day;
};
int main()
{Date d1;Date d2(d1);//也可以寫成Date d2=d1return 0;
}

4.3、默認拷貝構造函數

像上面介紹的默認成員函數一樣,當我們沒有在類中寫拷貝構造函數時,編譯器會自動生成一個默認的拷貝構造。

系統生成的拷貝構造也會針對成員變量的內置類型和自定義類型做一個區分。對于內置類型的成員變量,編譯器會按照被拷貝對象的內存存儲字節序完成拷貝,就好比被拷貝的對象有3個int類型成員變量,占12字節內存,編譯器會根據該對象的內存和成員初始值拷貝給新對象。

總結

本次我們介紹了,this指針、構造函數、析構函數、拷貝構造、等一些與類緊密關聯的知識。
要將他們詳細的介紹,所用篇幅過長,后續會出拓展版的

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

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

相關文章

中國的歷史看中國的經濟發展

從中國的歷史看中國的經濟發展&#xff0c;可以發現其經歷了幾個顯著的階段&#xff0c;每個階段都有其獨特的特點和成就&#xff1a; 古代經濟&#xff1a;中國古代經濟以農業為主&#xff0c;實行井田制&#xff0c;重視水利工程的建設&#xff0c;如都江堰、靈渠等。 商業發…

Compose Multiplatform 1.6.10 發布,解釋一些小問題, Jake 大佬的 Hack

雖然一直比較關注跨平臺開發&#xff0c;但其實我很少寫 Compose Multiplatform 的內容&#xff0c;因為關于 Compose Multiplatform 的使用&#xff0c;其實我并沒在實際生產環境上發布過&#xff0c;但是這個版本確實值得一提&#xff0c;因為該版本包含&#xff1a; iOS Bet…

數據庫(15)——DQL分頁查詢

DQL分頁查詢語法 SELECT 字段列表 FROM 表名 LIMIT 起始索引&#xff0c;查詢記錄數; 注&#xff1a;起始索引從0開始&#xff0c;起始索引&#xff08;查詢頁碼-1&#xff09;*每頁顯示記錄數。 如果查詢的是第一頁&#xff0c;可以省略起始索引。 示例&#xff1a;查詢第一頁…

【考研數學】概率論如何復習?跟誰好?

概率論一定要跟對老師&#xff0c;如果跟對老師&#xff0c;考研基本上能拿滿分 概率論在考研試卷中占比并不大&#xff0c;其中&#xff1a; 高等數學&#xff0c;90分&#xff0c;約占比60%; 線性代數&#xff0c;30分&#xff0c;約占比20%; 概率論與數理統計&#xff0…

hive中的join操作及其數據傾斜

hive中的join操作及其數據傾斜 join操作是一個大數據領域一個常見的話題。歸根結底是由于在數據量超大的情況下&#xff0c;join操作會使內存占用飆升。運算的復雜度也隨之上升。在進行join操作時&#xff0c;也會更容易發生數據傾斜。這些都是需要考慮的問題。 過去了解到很…

每日5題Day15 - LeetCode 71 - 75

每一步向前都是向自己的夢想更近一步&#xff0c;堅持不懈&#xff0c;勇往直前&#xff01; 第一題&#xff1a;71. 簡化路徑 - 力扣&#xff08;LeetCode&#xff09; class Solution {public String simplifyPath(String path) {Deque<String> stack new LinkedList…

mysql的增刪查改(進階)

目錄 一. 更復雜的新增 二. 查詢 2.1 聚合查詢 COUNT SUM AVG MAX MIN 2.1.2 分組查詢 group by 子句 2.1.3 HAVING 2.2 聯合查詢/多表查詢 2.2.1 內連接 2.2.2 外連接 2.2.3 全外連接 2.2.4 自連接 2.2.5 子查詢 2.2.6 合并查詢 一. 更復雜的新增 將從表名查詢到…

自動化辦公01 smtplib 郵件?動發送

目錄 一、準備需要發送郵件的郵箱賬號 二、發送郵箱的基本步驟 1. 登錄郵箱 2. 準備數據 3. 發送郵件 三、特殊內容的發送 1. 發送附件 2. 發送圖片 3. 發送超文本內容 4.郵件模板內容 SMTP&#xff08;Simple Mail Transfer Protocol&#xff09;即簡單郵件傳輸協議…

霍夫曼樹教程(個人總結版)

背景 霍夫曼樹&#xff08;Huffman Tree&#xff09;是一種在1952年由戴維霍夫曼&#xff08;David A. Huffman&#xff09;提出的數據壓縮算法。其主要目的是為了一種高效的數據編碼方法&#xff0c;以便在最小化總編碼長度的情況下對數據進行編碼。霍夫曼樹通過利用出現頻率…

【Qt秘籍】[009]-自定義槽函數/信號

自定義槽函數 在Qt中自定義槽函數是一個直接的過程&#xff0c;槽函數本質上是類的一個成員函數&#xff0c;它可以響應信號。所謂的自定義槽函數&#xff0c;實際上操作過程和定義普通的成員函數相似。以下是如何在Qt中定義一個自定義槽函數的步驟&#xff1a; 步驟 1: 定義槽…

<jsp:setProperty>設置有參構造函數創建的自定義對象的屬性

假設某一個類&#xff08;如TextConverter類&#xff09;有一個無參構造函數和一個有參構造函數&#xff0c;我們可以在Servlet里面先用有參構造函數自己new一個對象出來&#xff0c;存到request.setAttribute里面去。 Servlet轉發到jsp頁面后&#xff0c;再在jsp頁面上用<j…

django基于大數據+Spring的新冠肺炎疫情實時監控系統設計和實現

設計一個基于Django(后端)和Spring(可能的中間件或服務集成)的新冠肺炎疫情實時監控系統涉及多個方面,包括數據收集、數據處理、數據存儲、前端展示以及可能的中間件服務(如Spring Boot服務)。以下是一個大致的設計和實現步驟: 1. 系統架構 前端:使用Web框架(如Reac…

三種字符串的管理方式

NSString的三種實現方式 OC這個語言在不停的升級自己的內存管理&#xff0c;盡量的讓自己的 OC的字符串 問題引入 在學習字符串的過程中間會遇到一個因為OC語言更新造成的問題 例如&#xff1a; int main(int argc, const char * argv[]) {autoreleasepool {NSString* str1 …

C++核心編程類的總結封裝案例

C類的總結封裝案例 文章目錄 C類的總結封裝案例1.立方體類的封裝2.點與圓的關系的封裝3.總結 1.立方體類的封裝 在C中&#xff0c;我們可以定義一個立方體&#xff08;Cube&#xff09;類來封裝立方體的屬性和方法。立方體的屬性可能包括邊長&#xff08;side length&#xff…

【redis】set和zset常用命令

set 無序集合類型 sadd 和 smembers SADD&#xff1a;將一個或者多個元素添加到set中。注意,重復的元素無法添加到set中。 語法&#xff1a;SADD key member [member] 把集合中的元素,叫做member,就像hash類型中,叫做field類似. 返回值表示本次操作,添加成功了幾個元素. 時間復…

網絡原理——http/https ---http(1)

T04BF &#x1f44b;專欄: 算法|JAVA|MySQL|C語言 &#x1faf5; 今天你敲代碼了嗎 網絡原理 HTTP/HTTPS HTTP,全稱為"超文本傳輸協議" HTTP 誕?與1991年. ?前已經發展為最主流使?的?種應?層協議. 實際上,HTTP最新已經發展到 3.0 但是當前行業中主要使用的HT…

概念解析 | 為什么SAR中的天線間隔需要是四分之一波長?

注1:本文系“概念解析”系列之一,致力于簡潔清晰地解釋、辨析復雜而專業的概念。本次辨析的概念是:為什么SAR中的天線間隔需要是四分之一波長 概念解析 | 為什么SAR中的天線間隔需要是四分之一波長? 在這篇文章中,我們將深入探討**合成孔徑雷達(SAR)**系統中,為什么天…

明日周刊-第12期

以前小時候最期待六一兒童節了&#xff0c;父母總會給你滿足一個愿望&#xff0c;也許是一件禮物也許是一次陪伴。然而這個世界上其實還有很多兒童過不上兒童節&#xff0c;比如某些地區的小孩子&#xff0c;他們更擔心的是能不能見到明天的太陽。 文章目錄 一周熱點航天探索火…

LeetCode-77. 組合【回溯】

LeetCode-77. 組合【回溯】 題目描述&#xff1a;解題思路一&#xff1a;回溯背誦版解題思路三&#xff1a;0 題目描述&#xff1a; 給定兩個整數 n 和 k&#xff0c;返回范圍 [1, n] 中所有可能的 k 個數的組合。 你可以按 任何順序 返回答案。 示例 1&#xff1a; 輸入&a…

Python怎么使用 SQLAlchemy 和model 查詢數據呢?

SQLAlchemy是一個流行的Python SQL工具包和對象關系映射器&#xff08;ORM&#xff09;。 假設正在使用 SQLAlchemy 并有一個模型 MyModel&#xff0c;使用這個模型以及 query 方法來查詢數據庫。 這里有一個基本的例子&#xff0c;說明如何使用 SQLAlchemy 的 query 方法和 wi…