C++之初始化列表詳細剖析

一、初始化列表定義

初始化列表:以一個冒號開始,接著是一個以逗號分隔的數據成員列表,每個"成員變量"后面跟一個放在括號中的初始值或表達式。

class Date
{
public:Date(int year, int month, int day): _year(year), _month(month)//初始化列表, _day(day){}
private:int _year;int _month;int _day;
};

二、初始化列表內在作用的剖析

不知道大家有沒有想過這樣一個問題,成員函數明明可以在函數內部對成員變量進行賦值,那為什么還要搞出初始化列表這個東西呢?這個時候就需要我們對初始化列表有一個更加深刻的理解了。

我們知道,在一個類被設計出來的時候,它里面定義的成員變量只是變量的聲明,沒有為其分配空間。我們也知道,類定義出一個對象是在主函數中定義的,而創建出來的這個對象其中的成員變量其實是在初始化列表中定義的。那么假設我們創建出來的類的成員變量中含有引用類型或者是被const修飾時(引用類型和const修飾的變量在定義時就必須為其賦初始值),就像下面這個代碼:

?如果我們定義的類內部的成員變量中含有引用類型或者是被const修飾,而在成員函數體內部再對其賦初始值,就相當于_ref和_n兩個變量定義和賦初始值分離了,但我們明確地知道引用類型或者是被const修飾的變量在定義時就必須為其賦初始值,所以編譯器會報未初始化的錯誤。上面圖片中的代碼還可以寫的更明確一點,就相當于下面這種形式:

?五個成員變量全部定義和賦初始值分開,一般的內置類型是支持這種行為的。就像是這樣:

int main()
{int a;a = 10;//可以int& n;n = a;//報錯const int m;m = 10;//報錯return 0;
}

所以正確的方法應該是:類內部的成員變量中含有引用類型或者是被const修飾時,引用類型或者是被const修飾的成員變量必須用初始化列表賦初值(定義時就賦初值)。

class Date
{
private:int _year;int _month;int _day;int& _ref;const int _n;public:Date(int year, int month, int day):_year(),_month(),_day(),_ref(month),_n(1){this->_year = year;this->_month = month;this->_day = day;}
};

三、類中成員變量含有自定義類型的情況

很好理解,自定義也必須使用初始化列表進行初始化,如果自定義類型沒有顯示地調用初始化列表,那么自定義類型就會去調用它的默認構造函數,如果沒有默認構造函數,就會編譯報錯。

#include <iostream>
using namespace std;class A
{
private:int _a;public:A(int a = 0){this->_a = a;}
};class Date
{
private:int _year;int _month;int _day;A aa;int& _ref;const int _n;public:Date(int year, int month, int day):_year()  //aa沒有顯示地調用初始化列表,會去調用它的默認構造函數, _month()//剩下的三個成員沒有寫出來定義,但是它也會定義,只是內置類型給的隨機值, _day()  //自定義類型會去調用它的默認構造函數,_ref(month),_n(1){this->_year = year;this->_month = month;this->_day = day;}
};//編譯沒有報錯
int main()
{Date d1(2023, 11, 2);return 0;
}

?_a被初始化為了0。還是上面這段代碼,如果將A(int a = 0)改成A(int a),編譯就會報錯,因為沒有合適的默認構造函數。

所以自定義類型在使用初始化列表的時候,建議要顯示地傳參去調用指定的構造函數。

四、初始化列表使用的建議以及小點

盡量使用初始化列表初始化,因為不管你是否使用初始化列表,對于自定義類型成員變量,
一定會先使用初始化列表初始化。
但是我們能不能什么地方都用初始化而都不在函數體內部賦初始值呢?答案是不行的。初始化列表可以解決百分之九十的問題,但對于一些像判斷之類的語句還是要放在函數體內部的。像下面這個例子:
class Date
{
private:int _year;int _month;int _day;int* _aa;public:Date(int year, int month, int day):_year(year)  //aa沒有顯示地調用初始化列表,會去調用它的默認構造函數, _month(month)//剩下的三個成員沒有寫出來定義,但是它也會定義,只是內置類型給的隨機值, _day(day)  //自定義類型會去調用它的默認構造函數,_aa(new int [10]){if (_aa == nullptr){perror("new fail");exit(-1);}}~Date(){delete[] _aa;}
};int main()
{Date d1(2023, 11, 2);return 0;
}

這里有一個小點需要注意:. 成員變量在類中聲明次序就是其在初始化列表中的初始化順序,與其在初始化列表中的先后次序無關。

class A
{
public:A(int a):_a1(a), _a2(_a1){}void Print() {cout << _a1 << " " << _a2 << endl;}
private:int _a2;int _a1;
};int main() 
{A aa(1);aa.Print();
}

上面代碼_a2比_a1先聲明,所以_a2先初始化,用_a1初始化_a2,此時_a1為隨機值,所以初始化完_a2為隨機值,再用1初始化_a1,_a1為1。

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

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

相關文章

OpenCV快速入門:圖像分析——圖像分割和圖像修復

文章目錄 前言一、圖像分割1.1 漫水填充法1.1.1 漫水填充法原理1.1.2 漫水填充法實現步驟1.1.3 代碼實現 1.2 分水嶺法1.2.1 分水嶺法原理1.2.2 分水嶺法實現步驟1.2.3 代碼實現 1.3 GrabCut法1.3.1 GrabCut法原理1.3.2 GrabCut法實現步驟1.3.3 代碼實現 1.4 Mean-Shift法1.4.1…

論文閱讀 (106):Decoupling maxlogit for out-of-distribution detection (2023 CVPR)

文章目錄 1 概述1.1 要點1.2 代碼1.3 引用 2 預備知識3 方法3.1 MaxLogit3.2 改進MaxCosine和MaxNorm3.3 DML 1 概述 1.1 要點 題目&#xff1a;解耦最大logit分布外檢測 (Decoupling maxlogit for out-of-distribution detection) 方法&#xff1a; 提出了一種心機基于log…

多級緩存快速上手

哈嘍~大家好&#xff0c;這篇來看看多級緩存。 &#x1f947;個人主頁&#xff1a;個人主頁????? &#x1f948; 系列專欄&#xff1a;【微服務】 &#x1f949;與這篇相關的文章&#xff1a; JAVA進程和線程JAVA進程和線程-CSDN博客Http…

不做機器視覺工程師,轉行,轉崗的建議與想法

正所謂外行看熱鬧&#xff0c;內行看門道。提前咨詢前輩們&#xff0c;多問問&#xff0c;多看看。要做就做&#xff0c;一定要提前做好防范。 無論你是要轉行或者是轉崗&#xff0c;看你有沒有本錢和試錯成本 有些人&#xff0c;家庭好&#xff0c;可以一直去試錯和從頭再來。…

無線WiFi安全滲透與攻防(國外篇):使用 Aircrack-ng 破解 WEP 密碼

使用 Aircrack-ng 破解 WEP 密碼 使用 Aircrack-ng 破解 WEP 密碼一. 用 Aircrack-ng 破解 WEP 密碼 - 背景知識網卡與網卡芯片WEP 加密協議WEP 所使用的身份認證協議二. 使用 Aircrack-ng 破解 WEP 密碼 - 破解原理破解機理三. 使用 Aircrack-ng 破解 WEP 密碼 - aircrack-ng …

學習.NET驗證模塊FluentValidation的基本用法(續1:其它常見用法)

FluentValidation模塊支持鏈式驗證方法調用&#xff0c;也就是說&#xff0c;除了 RuleFor(r > r.UserName).NotEmpty()調用方式之外&#xff0c;還可以將對單個屬性的多種驗證函數以鏈式調用方式串接起來&#xff0c;比如UserName屬性不能為空&#xff0c;長度在5~10之間&a…

__attribute__((constructor))用法解析

__attribute__((constructor))是GCC和兼容的編譯器中的一個特性&#xff0c;用于指示編譯器將一個函數標記為在程序啟動時自動執行的初始化函數。 同樣的還有__attribute__((destructor))在main()函數后調用。 當你在一個函數聲明或定義前加上__attribute__((constructor))屬…

淺談 Guava 中的 ImmutableMap.of 方法的坑

作者&#xff1a;明明如月學長&#xff0c; CSDN 博客專家&#xff0c;大廠高級 Java 工程師&#xff0c;《性能優化方法論》作者、《解鎖大廠思維&#xff1a;剖析《阿里巴巴Java開發手冊》》、《再學經典&#xff1a;《EffectiveJava》獨家解析》專欄作者。 熱門文章推薦&…

vue項目下.env.development環境變量配置文件

.env.development 文件是一個用于開發環境配置的文件。在許多應用程序中&#xff0c;開發環境和生產環境具有不同的配置需求。.env.development 文件允許你在開發環境中定義特定的環境變量和配置選項。 一般來說&#xff0c;.env.development 文件用于存儲開發環境相關的配置信…

國自然項目基金撰寫的隱藏技巧、范例分析及提交前的自我審查

目錄 一、基金項目申請要求、重點及項目介紹 二、基金的撰寫技巧 三、基金撰寫的隱藏技巧 四、范例分析及提交前的自我審查 更多應用 基金項目申請需要進行跨學科的技術融合&#xff0c;申請人需要與不同領域結合&#xff0c;形成多學科交叉的研究。基金項目申請在新時期更…

由紅黑樹引出的HashMap擴容機制的思考

紅黑樹是什么&#xff1f; 三大特點&#xff1a; 根節點是黑色&#xff0c;葉節點是不存儲數據的黑色空節點 任何相鄰的兩個節點不能同時為紅色 任意節點到其可到達的節點間包含相同數量的黑色節點 聯想&#xff1a;Java HashMap底層紅黑樹原理 HashMap基于哈希表Map接口實…

快速掌握Pyqt5的三種主窗口

PyQt5是一個強大的跨平臺GUI框架&#xff0c;它提供了多種不同類型的主窗口類&#xff0c;以滿足不同的應用需求。下面是PyQt5中最常見的幾種主窗口類型及其創建方式的簡介&#xff1a; 1. QMainWindow QMainWindow是用于創建具有菜單欄、工具欄、狀態欄和中心窗口部件&#…

內存池 示例一

內存池是一種管理內存分配和釋放的技術&#xff0c;用于優化內存的使用效率。它通過預先分配一塊內存區域&#xff0c;并將其劃分為多個較小的塊&#xff08;內存塊池&#xff09;&#xff0c;然后按需分配這些內存塊來減少內存碎片化和頻繁的系統調用。這些內存塊可以是相同大…

Centos7.9配置nfs共享及rsync同步

客戶需求對oracle數據庫做一個跨機房的備份&#xff0c;原環境已做rman備份和每天expdp全庫導出&#xff0c;遠端只有虛擬化環境&#xff0c;可提供一個虛擬機&#xff0c;2個機房間網絡互通。 首先配置nfs服務端 查看操作系統版本 [rootnas199 ~]# more /etc/redhat-relea…

Python面經【1】

一、協程的相關概念 協程&#xff08;又稱微線程&#xff09;運行在線程之上&#xff0c;更加輕量級&#xff0c;協程并沒有增加線程總數&#xff0c;只是在線程的基礎上通過分時復用的方式運行多個協程&#xff0c;大大提高工程效率。 協程的特點&#xff1a; 輕量級&#…

WordPress站點屏蔽過濾垃圾評論教程(Akismet反垃圾評論插件)

前段時間我的WordPress站點經常收到垃圾評論的轟炸&#xff0c;嚴重時一天會收到幾十條垃圾評論。我這個小破站一沒啥流量&#xff0c;二又不盈利&#xff0c;實在是不太理解為啥有人要這么執著地浪費資源在上面。 Akismet反垃圾評論插件 其實用了 Akismet 反垃圾評論插件后&a…

快速掌握Pyqt5的6種按鈕

在PyQt5中&#xff0c;按鈕是構建用戶界面的基本元素之一&#xff0c;用于執行命令、啟動功能或觸發事件。PyQt5提供了多種類型的按鈕&#xff0c;每種都適用于不同的場景和需求。 1. QPushButton QPushButton 是最常用的按鈕類型&#xff0c;適用于大多數情況&#xff0c;如…

ARCore:在Android上構建令人驚嘆的增強現實體驗

ARCore&#xff1a;在Android上構建令人驚嘆的增強現實體驗 一、 AR 介紹1.1 AR技術簡介1.2 AR技術原理1.3 AR技術應用領域 二、Google的增強現實平臺ARCore2.1 ARCore簡介2.2 ARCore API介紹2.3 ARCore API使用示例 三、總結 一、 AR 介紹 增強現實 Augmented Reality&#x…

【算法-字符串2】替換空格 + 反轉單詞

今天&#xff0c;帶來字符串相關算法的講解。文中不足錯漏之處望請斧正&#xff01; 理論基礎點這里 1. 替換空格 題目描述&#xff1a;請實現一個函數&#xff0c;把字符串 s 中的每個空格替換成"%20"。 來源&#xff1a;力扣&#xff08;LeetCode&#xff09; 難…

Lettuce使用詳解

簡介特點連接池連接池特點連接池管理連接池優勢連接池配置參數 監控常用監控工具通過JMX監控通過Prometheus監控 代碼示例拓展springboot中通過jmx上報到Prometheus代碼示例更多Redis相關內容 簡介 Lettuce 是一個高級的、線程安全的 Redis 客戶端&#xff0c;用于與 Redis 數…