c++ 類和對象 —— 中 【復習筆記】

1. 類的默認成員函數

如果一個類什么成員都沒有,簡稱空類。但實際上,任何類在不寫成員時,編譯器會自動生成6個默認成員函數(用戶未顯式實現,編譯器生成的成員函數)

這6個成員函數可分為三類:

1. 初始化和清理:構造函數完成初始化工作;析構函數完成清理工作

2. 拷貝復制:拷貝構造是用同類對象初始化創建對象;賦值重載是把一個對象賦值給另一個對象

3. 取地址重載:普通對象和const對象取地址,這兩個很少自己實現

2. 構造函數

2.1 引入

class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}private:int _year;int _month;int _day;
};

對于上面的Date類,如果每次創建對象后要設置信息都要調用 Init 的公有方法,會有些麻煩。那能不能在創建對象時就能設置信息呢?構造函數便出現了

構造函數是一個特殊的成員函數,創建類類型對象時由編譯器自動調用,在對象整個生命周期內只調用一次

2.2 簡介

構造函數雖然叫構造,但它的作用不是開空間創建對象而是初始化對象

它具有以下特性:

1. 函數名和類名相同

2. 無返回值

3. 構造函數可以重載

4. 對象實例化時編譯器自動調用

5. 如果類沒有顯式定義構造函數,那編譯器會自動生成一個無參的默認構造函數;如果類顯式定義了,那編譯器不再生成

6. 構造函數對于類中內置類型成員不初始化,對于自定義類型成員調用它的默認成員函數(c++11中對于這一點打了補丁:內置類型成員在類中聲明時可以給默認值

7. 無參的構造函數和全缺省的構造函數都稱為默認構造函數,并且默認構造函數只有一個(即:無參構造函數、全缺省構造函數、編譯器自己默認生成的構造函數都是默認構造函數,但為了避免二義性,通常只定義一種)

?
class Time
{
public:Time(){cout << "Time()" << endl;_hour = 0;_minute = 0;_second = 0;}private:int _hour;int _minute;int _second;
};class Date
{
public:/*//一旦顯式定義任何構造函數,編譯器將不再生成Date(int year, int month, int day){_year = year;_month = month;_day = day;}*///無參構造函數//如果使用無參構造函數創建對象,對象后不加括號,否則就變成函數聲明Date(){}//帶參構造函數Date(int year, int month, int day){_year = year;_month = month;_day = day;}//全缺省構造函數//全缺省和無參可以看為函數重載,但在調用時會出現二義性Date(int year = 2025, int month = 1, int day = 1){_year = year;_month = month;_day = day;}private://內置類型,c++11內置成員變量可以在聲明時給默認值int _year;int _month;int _day;//自定義類型Time t;
};int main()
{Date d1;//調用無參構造函數Date d2(2025, 1, 1);//帶參構造函數return 0;
}?

3. 析構函數

3.1 引入

構造函數是完成初始化對象的工作的,和構造函數相反,析構函數就是完成對象中資源的清理工作(析構函數不完成對對象本身銷毀),對象銷毀時編譯器自動調用

3.2 簡介

析構函數具有以下特征:

1. 析構函數名是類名前加字符 ~

2. 無參數無返回類型

3. 一個類只能有一個析構函數,不能重載。如果沒顯式定義,系統自動生成默認析構函數

4. 對象生命周期結束,編譯器自動調用析構函數

5. 對于對象中內置類型,編譯器不需要資源清理,最后系統直接將其內存回收即可;對于自定義類型,會調用它的析構函數

6. 如果類沒有申請資源,析構函數可以不寫,使用生成的默認析構函數即可;但有資源申請時,一定要寫,否則會資源泄露

class Time
{
public:~Time(){cout << "~Time()" << endl;}
private:int _hour;int _minute;int _second;
};class Date
{
private://內置類型int _year = 2025;int _month = 1;int _day = 1;//自定義類型Time t;//創建Date對象,銷毀時要將Time類對象t銷毀,編譯器會給Date類生成一個默認析構函數//目的是調用Time類析構函數,確保Date對象銷毀時內部每個自定義對象都可以銷毀
};

4. 拷貝構造函數

4.1 引入

如果我們要創建一個和已經存在對象一樣的新對象,那拷貝構造函數便發揮作用

拷貝構造函數目的是用已經存在的類類型對象創建新對象,編譯器自動調用。所以它只有一個形參(對該類類型對象的引用,一般用const修飾)

4.2 簡介

它的特征如下:

1. 拷貝構造函數是構造函數的一個重載形式

2. 參數只有一個必須是該類類型對象的引用(用傳值方式直接報錯 --- 會引發無窮遞歸)

3. 如果沒有顯式定義,編譯器自動生成默認拷貝構造函數。(默認拷貝構造函數按內存存儲字節序完成拷貝,這種拷貝叫淺拷貝或值拷貝)

4. 對于默認拷貝構造函數,內置類型是淺拷貝,而自定義類型是調用其拷貝構造函數完成拷貝

(調用拷貝構造要傳參,傳參就要拷貝構造,拷貝構造就要傳參,傳參就要........,這也是為什么如果參數不是傳引用,就會引發無窮遞歸)

5. 如果類中沒涉及資源申請,拷貝構造可寫可不寫;一旦涉及資源申請,拷貝構造一定要寫,否則是淺拷貝。

(比如:我們創建了一個棧對象s1,在它的構造函數中申請10個元素的空間;然后對象s2使用s1拷貝構造,而類中沒有顯式定義拷貝構造函數,那編譯器自動生成默認拷貝構造函數,而這個拷貝構造是值拷貝,就會導致s1和s2指向同一塊空間。當銷毀s1和s2時,這個空間會釋放多次,導致程序崩潰)

6. 拷貝構造的調用場景:

?使用已存在對象創建新對象

?函數參數類型為類類型對象

?函數返回類型為類類型對象

一般對象傳參使用引用類型;返回時,如果場景允許引用(如非局部類對象.....)盡量使用引用

?
#include<iostream>
using namespace std;
class Date
{
public:Date(int year, int month, int day){cout << "Date(int,int,int):" << this << endl;}Date(const Date& d){cout << "Date(const Date& d):" << this << endl;}~Date(){cout << "~Date():" << this << endl;}
private:int _year;int _month;int _day;
};Date Test(Date d)
{//調用拷貝構造函數創建tempDate temp(d);//以值方式返回,調用拷貝構造構造臨時變量return temp;
}int main()
{//構造函數創建d1Date d1(2025, 1, 1);//傳值方式傳遞,調用拷貝構造函數Test(d1);return 0;
}?

5. 運算符重載

5.1 運算符重載

運算符重載是具有特殊函數名的函數,有函數名字、參數列表和返回值類型,返回值類型和參數列表和普通函數相似

函數名字:operator+要重載運算符符合(比如:operator< )

函數原型:返回值類型 operator操作符(參數列表)

注意事項:

1. 不能連接其他符號創建新操作符:operator@(這是錯誤的)

2. 重載操作符必須有一個類類型參數(即必須有一個自定義類型),操作符有幾個操作數,重載函數就有幾個參數

3. 用于內置類型的運算符,含義不能變

4. 作為類成員函數重載,形參看起來比操作數少1(成員函數第一個參數為隱藏的this)

5. 以下5個運算符不能重載:.*? ? ::? ? sizeof? ? ?? :? ? ?.

class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}//左操作數為this指針
bool operator==(const Date& d2)
{return _year == d2._year&& _month == d2._month&& _day == d2._day;
}private:int _year;int _month;int _day;
};//全局operator==
//如果成員變量是私有的,那無法訪問;重載成成員函數即可
/*bool operator==(const Date& d1, const Date& d2)
{return d1._year == d2._year&& d1._month == d2._month&& d1._day == d2._day;
}*/void Test()
{Date d1(2025, 1, 1);Date d2(2025, 2, 2);
}

5.2 賦值運算符重載

1. 格式:

參數類型:const T&,傳引用提高效率

返回值類型:T& ,返回引用提高效率,便于支持連續賦值

檢測是否給自己賦值

返回*this:符合連續賦值含義

2.特征:

?1. 賦值運算符只能重載成類的成員函數,不能重載成全局函數

(如果賦值運算符不顯示實現,編譯器默認生成。那再在類外自己實現一個全局賦值運算符重載,會導致沖突)

?2. 用戶沒顯式實現,編譯器自動生成一個默認賦值運算符重載(值拷貝的方式)

(內置類型成員變量直接復制,自定義類型要調用對應類的復制運算符重載)

3. 如果類為涉及資源管理,賦值運算符可寫可不寫;但涉及資源管理必須自己實現

(比如:我們創建了一個棧對象s1,在它的構造函數中申請10個元素的空間;然后對象s2的構造函數也申請10個元素的空間,s2=s1,編譯器會將s1的內容原封不動拷貝給s2,這導致s2的原空間丟失,內存泄漏;s1和s2共享一塊空間,后續會導致一份空間釋放兩次)

class Time
{
public:Time(){_hour = 1;_minute = 1;_second = 1;}Time& operator=(const Time& t){if (this != &t){_hour = t._hour;_minute = t._minute;_second = t._second;}return *this;}
private:int _hour;int _minute;int _second;
};class Date
{
public:Date(int year = 2025, int month = 1, int day = 1){_year = year;_month = month;_day = day;}Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}//賦值重載Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}
private://內置類型int _year;int _month;int _day;//自定義類型Time t;
};

5.3 前置++和后置++重載

class Date
{
public:Date(int year = 2025, int month = 1, int day = 1){_year = year;_month = month;_day = day;}//前置++//this指向對象在函數結束后不銷毀,用傳引用Date& operator++(){_day += 1;return *this;}//后置++//為了讓前置++和后置++區別,c++規定:后置++重載時多加一個int類型參數//但調用函數時這個參數不用傳遞,編譯器自動傳遞//tmp為臨時對象,只能傳值返回Date operator++(int){Date tmp(*this);_day += 1;return tmp;}private:int _year;int _month;int _day;
};

6. const成員

const修飾的“成員函數”稱為const成員函數,實際修飾該成員函數隱藏this指針,表示該成員函數中不能對類的任何成員進行修飾

class Date{public:Date(int year = 2025, int month = 1, int day = 1){_year = year;_month = month;_day = day;}//實際看為void print(const Date*this)void print()const{cout << "Print()const" << endl;cout << _year << endl;cout << _month << endl;cout << _day << endl;}private:int _year;int _month;int _day;};

注意事項:

1. 成員函數后面加const后,普通和const對象都可以調用

2. 不能所有成員函數都加const,比如要修改的對象成員變量的函數不能加

3. 只有成員函數內部不修改成員變量,都應該加const,這樣const對象和普通對象都可以調用

7. 取地址和const取地址操作符重載

這兩個默認成員函數一般不重新定義,編譯器會自己生成

class Date{public:Date* operator&(){return this;}const Date* operator&()const{return this;}private:int _year;int _month;int _day;};

使用編譯器默認取地址重載即可,特殊情況如:想讓別人獲取到指定內容,才重載

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

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

相關文章

數學建模:MATLAB循環神經網絡

一、簡述 1.循環神經網絡 循環神經網絡&#xff08;RNN&#xff09;是一種用于處理序列數據的神經網絡。不同于傳統的前饋神經網絡&#xff0c;RNN在隱藏層中加入了自反饋連接&#xff0c;使得網絡能夠對序列中的每個元素執行相同的操作&#xff0c;同時保持一個“記憶”狀態…

在windows10系統上安裝docker,然后在容器中運行GPU版本的Pytorch,并使用vscode連接該容器

一 . 安裝Docker Desktop 首先打開網址https://docs.docker.com/desktop/install/windows-install/ 下載完后&#xff0c;雙擊下面的exe文件進行安裝&#xff0c;默認情況下&#xff0c;Docker Desktop 安裝在C:\Program Files\Docker\Docker 出現提示時&#xff0c;請確保…

基于SpringBoot + Vue 的房屋租賃系統

基于springboot的房屋租賃管理系統-帶萬字文檔 SpringBootVue房屋租賃管理系統 送文檔 本項目有前臺和后臺兩部分、多角色模塊、不同角色權限不一樣 共分三種角色&#xff1a;用戶、管理員、房東 管理員&#xff1a;個人中心、房屋類型管理、房屋信息管理、預約看房管理、合…

C++特性——智能指針

為什么需要智能指針 對于定義的局部變量&#xff0c;當作用域結束之后&#xff0c;就會自動回收&#xff0c;這沒有什么問題。 當時用new delete的時候&#xff0c;就是動態分配對象的時候&#xff0c;如果new了一個變量&#xff0c;但卻沒有delete&#xff0c;這會造成內存泄…

C語言之 循環語句:程序運行的核心動力(上)

個人主頁&#xff1a;strive-debug 在 C 語言中&#xff0c;分支結構可以通過 if、switch 語句來實現&#xff0c;循環結構則可以通過 for、while、do while 語句來實現。 if 語句 if 語句的語法形式如下&#xff1a; if (表達式)語句; 如果表達式成立&#xff08;為真&am…

FreeRTOSBug解析:一個任務printf打印一半突然跳轉另一個任務,導致另一個任務無法打印

bug現象&#xff1a; key任務&#xff1a; 默認任務&#xff1a; 此時兩個任務的優先級相同&#xff0c;搶占式調度&#xff0c;時間片輪轉&#xff0c;空閑任務讓步。 但是會出現一個問題&#xff0c;key任務在發送完隊列之后不會立即跳轉到默認任務的隊列接收函數后的print…

操作系統八股文整理(一)

操作系統八股文整理 一、進程和線程的區別二、進程與線程的切換過程一、進程切換進程切換的步驟&#xff1a; 二、線程切換線程切換的步驟&#xff1a; 三、進程切換與線程切換的對比四、上下文切換的優化 三、系統調用一、系統調用的觸發二、從用戶空間切換到內核空間三、執行…

卷積神經網絡(CNN)之 EfficientNet

在深度學習領域&#xff0c;模型的計算效率與性能之間的平衡一直是一個核心挑戰。隨著卷積神經網絡&#xff08;CNN&#xff09;在圖像分類、目標檢測等任務中取得顯著成果&#xff0c;模型的復雜度和計算需求也急劇增加。2019年&#xff0c;Google Research 提出的 EfficientN…

學生選課管理系統數據庫設計報告

學生選課管理系統數據庫設計報告 一、需求分析 &#xff08;一&#xff09;項目背景 學生選課管理系統是高校教學管理的重要組成部分&#xff0c;旨在實現學生選課、課程管理、成績錄入與查詢等功能的自動化和信息化。通過該系統&#xff0c;學生可以方便地選擇課程&#xf…

工具介紹《Awsome-Redis-Rogue-Server 與 redis-rogue-server》

1. 核心功能與攻擊場景 redis-rogue-server 基于Redis主從復制漏洞&#xff08;CVE未公開&#xff09;&#xff0c;針對Redis 4.x~5.0.5版本設計&#xff0c;通過偽造惡意主節點強制同步惡意模塊&#xff08;.so文件&#xff09;實現遠程代碼執行&#xff08;RCE&#xff09;。…

Razor C# 變量

Razor C# 變量 引言 在ASP.NET MVC和Razor視圖引擎中,變量是構建動態網頁的基礎。理解Razor C#變量的使用對于開發者來說至關重要。本文將詳細介紹Razor C#變量的概念、類型、作用域以及如何在實際項目中有效使用它們。 一、Razor C# 變量的概念 Razor C# 變量是存儲在Raz…

【QA】模板方法模式在Qt中有哪些應用?

在 Qt 框架中&#xff0c;模板方法模式&#xff08;Template Method Pattern&#xff09;被廣泛應用于框架的設計中&#xff0c;通過定義算法骨架并允許子類在不改變結構的情況下重寫部分步驟。以下是 Qt 中典型的應用場景及示例&#xff1a; 1. 事件處理&#xff08;Event Ha…

有趣的算法實踐:整數反轉與回文檢測(Java實現)

題目描述&#xff1a;整數反轉與回文檢測 要求實現兩個功能&#xff1a; 將輸入的整數反轉&#xff08;保留符號&#xff0c;如輸入-123返回-321&#xff09;判斷反轉后的數是否為回文數&#xff08;正反讀相同&#xff09; 示例&#xff1a; 輸入&#xff1a;123 → 反轉結…

【協作開發】低成本一鍵復刻github的gitea

在閱讀 next-public 時&#xff0c;反思原本的需求&#xff0c;是否本未倒置&#xff0c;故而重新調研當下開源現狀。發現 gitea 完全滿足商業軟件的開發要求&#xff0c;并且價格足夠低&#xff0c;使用足夠方便&#xff0c;其他同類軟件完全不用看了&#xff0c;真是世界級的…

基于“動手學強化學習”的知識點(二):第 15 章 模仿學習(gym版本 >= 0.26)

第 15 章 模仿學習&#xff08;gym版本 &#xff1e; 0.26&#xff09; 摘要 摘要 本系列知識點講解基于動手學強化學習中的內容進行詳細的疑難點分析&#xff01;具體內容請閱讀動手學強化學習&#xff01; 對應動手學強化學習——模仿學習 # -*- coding: utf-8 -*-import gy…

JAVA面試_進階部分_Java JVM:垃圾回收(GC 在什么時候,對什么東西,做了什么事情)

在什么時候&#xff1a; 首先需要知道&#xff0c;GC又分為minor GC 和 Full GC&#xff08;major GC&#xff09;。Java堆內存分為新生代和老年代&#xff0c;新生代 中又分為1個eden區和兩個Survior區域。 一般情況下&#xff0c;新創建的對象都會被分配到eden區&#xff…

2024年消費者權益數據分析

&#x1f4c5; 2024年315消費者權益數據分析 數據見&#xff1a;https://mp.weixin.qq.com/s/eV5GoionxhGpw7PunhOVnQ 一、引言 在數字化時代&#xff0c;消費者維權數據對于市場監管、商家誠信和行業發展具有重要價值。本文基于 2024年315平臺線上投訴數據&#xff0c;采用數…

設計模式Python版 訪問者模式

文章目錄 前言一、訪問者模式二、訪問者模式示例 前言 GOF設計模式分三大類&#xff1a; 創建型模式&#xff1a;關注對象的創建過程&#xff0c;包括單例模式、簡單工廠模式、工廠方法模式、抽象工廠模式、原型模式和建造者模式。結構型模式&#xff1a;關注類和對象之間的組…

安全無事故連續天數計算,python 時間工具的高效利用

安全天數計算&#xff0c;數據系統時間直取&#xff0c;安全標準高效便捷好用。 筆記模板由python腳本于2025-03-17 23:50:52創建&#xff0c;本篇筆記適合對python時間工具有研究欲的coder翻閱。 【學習的細節是歡悅的歷程】 博客的核心價值&#xff1a;在于輸出思考與經驗&am…

大型語言模型(LLM)部署中的內存消耗計算

在部署大型語言模型&#xff08;LLM&#xff09;時&#xff0c;顯存&#xff08;VRAM&#xff09;的合理規劃是決定模型能否高效運行的核心問題。本文將通過詳細的公式推導和示例計算&#xff0c;系統解析模型權重、鍵值緩存&#xff08;KV Cache&#xff09;、激活內存及額外開…