【C++ | 構造函數】類的構造函數詳解

😁博客主頁😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客內容🤑:🍭嵌入式開發、Linux、C語言、C++、數據結構、音視頻🍭
?發布時間?:2024-06-06 09:02:26

本文未經允許,不得轉發!!!

目錄

  • 🎄一、為什么需要構造函數
  • 🎄二、什么是構造函數
  • 🎄三、使用構造函數
  • 🎄四、默認構造函數
  • 🎄五、成員初始化列表
  • 🎄六、總結


在這里插入圖片描述

🎄一、為什么需要構造函數

C++的目標之一是讓使用類對象就像使用標準類型一樣。如果沒有構造函數,就無法創建對象并初始化。下面代碼演示了CDate類對象初始化時會報錯。

int year = 2001// 有效初始化struct thing
{char * pn;int m;
};
thing amabob = {"wodget", -23};	// 有效初始化class CDate
{int year;int mon;int day;
};
CDate date = {2024, 06, 05}; // 編譯報錯

這里CDate類對象初始化出錯的原因是,數據部分是私有的,只能通過類成員函數去訪問,如果將數據設置為公有會違背“數據隱藏”的思想。所以,我們需要一個成員函數,能夠在創建對象時初始化數據部分。C++提供了這樣的函數——構造函數。


在這里插入圖片描述

🎄二、什么是構造函數

構造函數:專門用于構造新對象、 將值賦給它們的數據成員。

構造函數的函數名類名相同,沒有返回值類型,會在創建對象時自動調用一次,目的是初始化對象。

下面看看怎樣聲明和定義構造函數?CDate 類為例,代碼如下:

class CDate
{
public:CDate(int year, int mon, int day); // 構造函數聲明
private:int m_year;int m_mon;int m_day;
};// 構造函數定義
CDate::CDate(int year, int mon, int day)
{m_year = year;m_mon = mon;m_day = day;
}

在編寫類成員函數時,需要注意,參數名不能和類成員名相同,否則最終代碼會寫出year=year,為了避免這種情況,常見的做法是在數據成員前加m_前綴表示其為類成員。


在這里插入圖片描述

🎄三、使用構造函數

C++提供了兩種使用構造函數來初始化對象的方式。

  • 1、顯式地調用構造函數:
    CDate date = CDate(2024,6,5);
    
  • 2、隱式地調用構造函數:
    CDate date(2024,6,5);	// 這種形式更緊湊
    

每次創建類對象(甚至使用 new 動態分配內存)時,C++都自動調用類構造函數。下面是將構造函數與 new 一起使用的方法,這種情況下,對象沒有名稱,但可以使用指針來管理該對象:

CDate *pDate = new CDate(2024,6,5);

另外,如果編譯器支持C++11,則支持下面三種寫法:

CDate date = {2024,6,5};	// C++11
CDate date{2024,6,5};
CDate *pDate = new CDate{2024,6,5};

注意:無法使用對象來調用構造函數,因為在構造函數構造出對象之前,對象是不存在的。因此構造函數被用來創建對象,而不能通過對象來調用。

結合上個小節,下面代碼演示了怎么聲明、定義、使用構造函數:

// g++ 09_Construct_Date.cpp
#include <iostream>using namespace std;class CDate
{
public:CDate(int year, int mon, int day); // 構造函數聲明void show(){cout << "Date: " << m_year << "." << m_mon << "." << m_day << endl;}private:int m_year;int m_mon;int m_day;
};// 構造函數定義
CDate::CDate(int year, int mon, int day)
{m_year = year;m_mon = mon;m_day = day;
}int main()
{CDate date = CDate(2024,6,5);date.show();CDate date1(2024,6,6);date1.show();CDate *pDate = new CDate(2024,6,7);pDate->show();return 0;
}

運行結果:
在這里插入圖片描述


在這里插入圖片描述

🎄四、默認構造函數

首先要清楚一點,構造函數可以存在多個,并且形成重載的關系,編譯器會根據參數自動選擇調用那個構造函數。我們可以改一下上面代碼的類如下,多了兩個重載的構造函數:

class CDate
{
public:CDate(int year, int mon, int day);	// 構造函數聲明CDate(int year, int mon);			// 構造函數聲明CDate();							// 構造函數聲明void show(){cout << "Date: " << m_year << "." << m_mon << "." << m_day << endl;}private:int m_year;int m_mon;int m_day;
};

默認構造函數:如果類沒有提供任何的構造函數,則編譯器會自動提供一個默認構造函數,它沒有參數,也不做任何工作。
CDate 類的默認構造函數可能如下:

CDate::CDate(){
}

在未提供顯式初始值去創建對象時會調用默認構造函數,如下:

CDate date;	// 未顯示提供初始值,會調用默認構造函數

注意:如果類提供了構造函數,則編譯器就不會在提供默認構造函數。如果該類需要使用默認構造函數,則需要程序員在類中為其提供默認構造函數,或者將其中一個構造函數的參數都給默認值。

在設計類時, 通常應提供對所有類成員做隱式初始化的默認構造函數。

上個小節代碼中,我們為 CDate 類只提供了一個帶有構造函數,所以,如果程序中使用 CDate date; 則會報錯:error: no matching function for call to ‘CDate::CDate()’,下面我們修改一下,為其提供一個默認構造函數:

// g++ 09_Construct_Date.cpp
#include <iostream>using namespace std;class CDate
{
public:CDate(int year, int mon, int day);	// 構造函數聲明CDate(){}							// 默認構造函數void show(){cout << "Date: " << m_year << "." << m_mon << "." << m_day << endl;}private:int m_year;int m_mon;int m_day;
};// 構造函數定義
CDate::CDate(int year, int mon, int day)
{m_year = year;m_mon = mon;m_day = day;
}int main()
{CDate date = CDate(2024,6,5);date.show();CDate date1(2024,6,6);date1.show();CDate *pDate = new CDate(2024,6,7);pDate->show();CDate date_default;date_default.show();return 0;
}

運行結果如下:date_default 對象的值是亂碼,因為我們的提供的默認構造沒做任何東西,正常編寫代碼時會做一些初始化動作。
在這里插入圖片描述


在這里插入圖片描述

🎄五、成員初始化列表

在C++中,const修飾的變量必須初始化,引用也必須初始化。如果一個類存在const成員或引用成員,則上面的構造函數無法對這兩類成員進行初始化。C++為構造函數提供了 成員初始化列表 來解決這類問題。

成員初始化列表:成員初始化列表由逗號分隔的初始化列表組成(前面帶冒號)。它位于構造函數參數列表的右括號之后、函數體左括號之前。

CDate 類的 成員初始化列表 可以寫成下面代碼:

CDate():m_year(2024), m_mon(1), m_day(1)
{}

注意成員初始化列表 只能在構造函數中使用。一旦類中出現const成員引用成員,則編譯器會要求每個構造函數都去初始化這兩類成員,且必須使用 成員初始化列表

下面對上個小節的代碼修改一下,在 CDate 類中聲明一個 const 變量,代碼如下:

// g++ 09_Construct_Date.cpp
#include <iostream>using namespace std;class CDate
{
public:CDate(int year, int mon, int day);	// 構造函數聲明//CDate(){}							// 默認構造函數CDate():Month(12)					// 默認構造函數{//Month = 12;		// 報錯:assignment of read-only member ‘CDate::Month’m_year = 2024;m_mon = 1;m_day = 1;}void show(){cout << "Date: " << m_year << "." << m_mon << "." << m_day << endl;}private:int m_year;int m_mon;int m_day;const int Month;
};// 構造函數定義
CDate::CDate(int year, int mon, int day):Month(12)
{m_year = year;m_mon = mon;m_day = day;
}int main()
{CDate date = CDate(2024,6,5);date.show();CDate date1(2024,6,6);date1.show();CDate *pDate = new CDate(2024,6,7);pDate->show();CDate date_default;date_default.show();return 0;
}

在這里插入圖片描述

🎄六、總結

👉本文詳細介紹了C++中的構造函數,怎樣聲明、定義、使用構造函數,默認構造函數,構造函數的成員初始化列表。

在這里插入圖片描述
如果文章有幫助的話,點贊👍、收藏?,支持一波,謝謝 😁😁😁

參考:
《C++ Primer Plus》

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

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

相關文章

HCIA-RS基礎-VLAN配置

目錄 前言創建拓撲創建VLAN查看創建的VLAN配置trunk口并放行VLAN配置access接口查看所有vlan基本信息測試網絡連通性命令合集 前言 VLAN定義&#xff1a;VLAN是一種將局域網內的設備從邏輯上劃分成一個個網段&#xff0c;從而實現虛擬工作組的新興數據交換技術。VLAN優點&…

設計模式-單例模式(創建型)

創建型-單例模式 了解單例 單例模式是一種創建型設計模式&#xff0c;它提供了一種創建對象的最佳方式;它必須保證&#xff1a; 單例類只能有一個實例化對象&#xff1b;單例類必須創建自己的唯一實例&#xff1b;單例類必須給其他對象提供實例&#xff1b; 另外&#xff1a;…

【面試筆記】嵌入式軟件工程師,汽車電子軟件相關

文章目錄 1. C語言基礎1.1 const1.2 static1.3 回調函數的用法1.4 宏定義1.5 編譯、鏈接過程1.6 堆與棧的區別&#xff1f;1.7 簡單的字符串算法題&#xff0c;C語言實現1.7.1 給定一個字符串&#xff0c;按順序篩選出不重復的字符組成字符串&#xff0c;輸出該字符串1.7.2 給定…

Python3 迭代器和生成器

前言 本文主要介紹Python中的迭代器和生成器&#xff0c;主要內容包括 迭代器概述、生成器簡介。 文章目錄 前言一、迭代器簡介二、生成器簡介 一、迭代器簡介 在 Python 中&#xff0c;迭代器(iterator)是一個實現了迭代器協議&#xff08;Iterator Protocol&#xff09;的…

opencv進階 ——(十一)基于RMBG實現生活照生成寸照

實現步驟 1、檢測人臉&#xff0c;可以使用opencv自帶的級聯分類器或者dlib實現人臉檢測 2、放大人臉范圍&#xff0c;調整到正常寸照尺寸 3、基于RMGB算法得到人像掩碼 4、生成尺寸相同的純色背景與當前人像進行ALPHA融合即可 alpha融合實現 void alphaBlend(cv::Mat&…

1 機器人軟件開發學習所需通用技術棧(一)

機器人軟件工程師技術路線&#xff08;如有缺失&#xff0c;歡迎補充&#xff09; 1. 機器人軟件開發工程師技術路線 1.1 基礎知識 C/C編程&#xff1a;掌握C/C語言基礎&#xff0c;包括數據結構、算法、內存管理等。操作系統&#xff1a;了解Linux或Windows等操作系統的基本…

android 13 aosp 預置so庫

展訊對應的main.mk配置 device/sprd/qogirn**/ums***/product/***_native/main.mk $(call inherit-product-if-exists, vendor/***/build.mk)vendor/***/build.mk PRODUCT_PACKAGES \libtestvendor///Android.bp cc_prebuilt_library_shared{name:"libtest",srcs:…

2.1 初識Windows程序

Windows程序設計是一種面向對象的編程。Windows操作系統以數據結構的形式定義了大量預定義的對象作為操作系統的數據類型。Windows動態鏈接庫提供了各種各樣的API接口函數供Windows應用程序調用。一個Windows應用程序是運行在Windows操作系統之上的。這些API接口函數的調用所實…

1349:【例4-10】最優布線問題

【解題思路】 最小生成樹模板題&#xff0c;求最小生成樹所有邊權加和。 該題輸入的是鄰接矩陣&#xff0c;因此使用鄰接矩陣解決該問題。當然也可以保存為鄰接表。 【參考代碼】 //示例代碼 Prim算法 #include <iostream> #include <cstring> #include <cs…

【Vue】路由的基本使用

文章目錄 一、固定5個固定的步驟二、代碼示例三、兩個核心步驟四、完整代碼 vue-router插件作用 修改地址欄路徑時&#xff0c;切換顯示匹配的組件 說明 Vue 官方的一個路由插件&#xff0c;是一個第三方包 官網 https://v3.router.vuejs.org/zh/ VueRouter的使用&#xff0…

TCP/IP協議介紹——三次握手四次揮手

TCP/IP&#xff08;Transmission Control Protocol/Internet Protocol&#xff0c;傳輸控制協議/網際協議&#xff09;是指能夠在多個不同網絡間實現信息傳輸的協議簇。TCP/IP協議不僅僅指的是TCP 和IP兩個協議&#xff0c;而是指一個由FTP、SMTP、TCP、UDP、IP等協議構成的協議…

CSS學習|css三種導入方式、基本選擇器、層次選擇器、結構偽類選擇器、屬性選擇器、字體樣式、文本樣式

第一個css程序 css程序都是在style標簽中書寫 打開該網頁&#xff0c;可以看到h1標簽中的我是標題被渲染成了紅色 可以在同級目錄下創建一個css目錄&#xff0c;專門存放css文件&#xff0c;可以和html分開編寫 然后在html頁面中&#xff0c;利用link標簽以及css文件地址&…

大模型基架:Transformer如何做優化?

大模型的基礎模式是transformer&#xff0c;所以很多芯片都實現先專門的transformer引擎來加速模型訓練或者推理。本文將拆解Transformer的算子組成&#xff0c;展開具體的數據流分析&#xff0c;結合不同的芯片架構實現&#xff0c;分析如何做性能優化。 Transformer結構 tr…

go的反射和斷言

在go中對于一個變量&#xff0c;主要包含兩個信息變量類型&#xff08;type&#xff09;和變量值&#xff08;value&#xff09; 可以通過reflect包在運行的時候動態獲取變量信息&#xff0c;并能夠進行操作 對于Type可以通過reflect.TypeOf()獲取到變量的類型信息 reflect.Ty…

13_前端工程化_ES6

1.前端工程化概念 前端工程化是使用軟件工程的方法來單獨解決前端的開發流程中模塊化、組件化、規范化、自動化的問題,其主要目的為了提高效率和降低成本。 前后端分離&#xff08;前端代碼工程化獨立出來形成一個單獨的app&#xff09; 1.開發分離 2.部署分離 3.服務器分離…

信號(上)

本節目標&#xff1a; 1. 掌握Linux信號的基本概念 2. 掌握信號產生的一般方式 3. 理解信號遞達和阻塞的概念&#xff0c;原理。 4. 掌握信號捕捉的一般方式。 5. 重新了解可重入函數的概念。 6. 了解競態條件的情景和處理方式 7. 了解SIGCHLD信號&#xff0c; 重新編寫信號處理…

ChatGPT基本原理詳細解說

ChatGPT基本原理詳細解說 引言 在人工智能領域&#xff0c;自然語言處理&#xff08;NLP&#xff09;一直是研究的熱點之一。隨著技術的發展&#xff0c;我們見證了從簡單的聊天機器人到復雜的語言模型的演變。其中&#xff0c;ChatGPT作為一項突破性技術&#xff0c;以其強大…

【Vue】自定義指令-v-loading指令的封裝

場景 實際開發過程中&#xff0c;發送請求需要時間&#xff0c;在請求的數據未回來時&#xff0c;頁面會處于空白狀態 > 用戶體驗不好 需求 封裝一個 v-loading 指令&#xff0c;實現加載中的效果 分析 本質 loading效果就是一個蒙層&#xff0c;蓋在了盒子上 數據請求…

從零開始精通Onvif之設備發現

設備發現的意義 在復雜的網絡環境中&#xff0c;如何快速而準確地識別網絡上的Onvif設備&#xff0c;對于攝像頭廠商、系統集成商、開發人員乃至最終用戶來說&#xff0c;都顯得至關重要。 首先&#xff0c;設備發現有效簡化了集成的復雜度。在沒有統一標準之前&#xff0c;每個…

2004NOIP普及組真題 2. 花生采摘

線上OJ&#xff1a; 【04NOIP普及組】花生采摘 核心思想&#xff1a; 1、本題為貪心即可。 2、因為本題嚴格限制了順序&#xff0c;所以先把每個節點的花生數量按降序排序。然后逐一判斷下一個花生是否需要去采摘即可 3、每一次采摘完&#xff0c;記錄耗時 t 以及采集的花…