C++類和對象之初始化列表

初始化列表

  • C++初始化列表詳解:性能優化與正確實踐
    • 什么是初始化列表?
    • 初始化列表的三大核心作用
      • 1. 性能優化:避免不必要的賦值操作
      • 2. 強制初始化:處理const和引用成員
      • 3. 基類初始化:正確調用父類構造函數
      • 4.必須使用初始化列表的情況
        • 1. 引用(Reference)
        • 2. `const` 成員變量
        • 3. 沒有默認構造函數的類類型成員
        • 為什么不能在構造函數體中初始化?
    • 初始化列表的語法規則
      • 1. 初始化順序由聲明順序決定
      • 2. 支持表達式初始化
    • 初始化列表 vs 構造函數體賦值
    • 總結

在這里插入圖片描述

C++初始化列表詳解:性能優化與正確實踐

在C++編程中,初始化列表是構造函數的重要組成部分,它不僅能提升代碼性能,還能確保成員變量被正確初始化。本文將深入探討初始化列表的語法、應用場景及最佳實踐。

什么是初始化列表?

初始化列表是構造函數的一部分,用于在對象創建時直接初始化成員變量。它位于構造函數參數列表之后,函數體之前,使用冒號(:)和逗號(,)分隔各成員的初始化操作。

class MyClass {
private:int value;std::string name;const double pi;int& ref;public:// 使用初始化列表的構造函數MyClass(int val, const std::string& nm, int& r): value(val), name(nm), pi(3.14159), ref(r) {// 構造函數體}
};

初始化列表的三大核心作用

1. 性能優化:避免不必要的賦值操作

對于非基本類型(如std::stringstd::vector),初始化列表可以直接調用其構造函數,而不是先默認構造再賦值。

對比示例:

// 使用初始化列表(高效)
class A {
public:A(const std::string& str) : data(str) {} // 直接構造
private:std::string data;
};// 使用賦值(低效)
class B {
public:B(const std::string& str) { data = str; } // 默認構造 + 賦值
private:std::string data;
};

2. 強制初始化:處理const和引用成員

const成員和引用必須在初始化時賦值,初始化列表是唯一的方式。

class Config {
private:const int maxSize;      // 常量成員std::string& filePath;  // 引用成員public:Config(int size, std::string& path) : maxSize(size), filePath(path) {} // 必須在初始化列表中賦值
};

3. 基類初始化:正確調用父類構造函數

當基類沒有默認構造函數時,必須通過初始化列表顯式調用其帶參構造函數。

class Base {
public:Base(int value) { /* ... */ }
};class Derived : public Base {
public:Derived(int x) : Base(x) { /* ... */ } // 調用基類構造函數
};

4.必須使用初始化列表的情況

在C++中,引用、const成員變量以及沒有默認構造函數的類類型成員變量必須在構造函數初始化列表中進行初始化,這是由它們的語義和C++對象生命周期的規則決定的。

1. 引用(Reference)

引用的本質是對象的別名,一旦綁定到某個對象就無法重新綁定。因此:

  • 必須在創建時初始化:引用沒有“未初始化”狀態,必須在定義時指定其引用的對象。
  • 構造函數體執行前成員已初始化:構造函數體中的代碼執行時,成員變量已經完成初始化。若在構造函數體內對引用賦值,實際上是對已初始化的引用進行賦值操作(改變被引用對象的值),而非初始化引用本身。

示例

class Example {
private:int& ref;  // 引用必須初始化
public:Example(int& value) : ref(value) {}  // 正確:初始化列表中初始化
};
2. const 成員變量

const成員變量的值在對象的生命周期內不可修改,因此:

  • 必須在初始化時賦值const變量一旦初始化就不能再被賦值。
  • 初始化列表是唯一機會:構造函數體執行前,const成員必須已經被賦予初始值。

示例

class Example {
private:const int value;  // const成員必須初始化
public:Example(int val) : value(val) {}  // 正確:初始化列表中初始化
};
3. 沒有默認構造函數的類類型成員

如果一個類沒有默認構造函數(即沒有無參構造函數),則在創建該類的對象時必須顯式提供參數。因此:

  • 必須通過參數初始化:編譯器無法默認構造該成員,必須顯式調用其帶參構造函數。
  • 初始化列表提供了顯式調用的機會:在初始化列表中,可以指定參數來調用成員的帶參構造函數。

示例

class Inner {
public:Inner(int x) {}  // 只有帶參構造函數
};class Example {
private:Inner inner;  // Inner沒有默認構造函數
public:Example(int x) : inner(x) {}  // 正確:顯式調用Inner的帶參構造函數
};
為什么不能在構造函數體中初始化?

構造函數體中的代碼執行時,成員變量已經完成初始化(默認初始化或編譯器生成的初始化)。因此:

  • 引用和const成員:無法在構造函數體中重新初始化,因為它們必須在初始化時就確定值。
  • 無默認構造函數的類成員:如果未在初始化列表中顯式構造,編譯器會嘗試調用其默認構造函數,但由于該類沒有默認構造函數,會導致編譯錯誤。

初始化列表的作用是在對象的內存分配后、構造函數體執行前,顯式控制成員變量的初始化過程。對于引用、const成員和無默認構造函數的類成員,初始化列表是唯一能滿足其初始化語義的地方。若不使用初始化列表,代碼將因“未初始化的引用/const成員”或“無法默認構造的類成員”而編譯失敗。

初始化列表的語法規則

1. 初始化順序由聲明順序決定

成員變量的初始化順序由其在類中聲明的順序決定,而非初始化列表中的順序。錯誤的順序可能導致未定義行為。

class Example {
private:int a;int b;public:// 危險:初始化列表順序與聲明順序不一致Example(int value) : b(value), a(b) {} // a先被初始化,但此時b未初始化
};

2. 支持表達式初始化

可以使用常量、函數返回值或其他成員變量進行初始化。

class Point {
private:int x;int y;int distance;public:Point(int _x, int _y) : x(_x), y(_y), distance(calculateDistance(_x, _y)) {} // 使用函數返回值初始化int calculateDistance(int x, int y) const {return std::sqrt(x*x + y*y);}
};

初始化列表 vs 構造函數體賦值

特性初始化列表構造函數體賦值
執行時機對象創建時對象創建后
性能通常更高效可能涉及額外的賦值操作
const/引用成員支持不支持
基類初始化必須使用不可用

總結

初始化列表總結:

  1. ?論是否顯?寫初始化列表,每個構造函數都有初始化列表;
  2. ?論是否在初始化列表顯?初始化成員變量,每個成員變量都要?初始化列表初始化;在這里插入圖片描述

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

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

相關文章

continue通過我們的開源 IDE 擴展和模型、規則、提示、文檔和其他構建塊中心,創建、共享和使用自定義 AI 代碼助手

?一、軟件介紹 文末提供程序和源碼下載 Continue 使開發人員能夠通過我們的開源 VS Code 和 JetBrains 擴展以及模型、規則、提示、文檔和其他構建塊的中心創建、共享和使用自定義 AI 代碼助手。 二、功能 Chat 聊天 Chat makes it easy to ask for help from an LLM without…

基于Spring Boot + Vue的母嬰商城系統( 前后端分離)

一、項目背景介紹 隨著母嬰行業在互聯網平臺的快速發展,越來越多的家庭傾向于在線選購母嬰產品。為了提高商品管理效率和用戶購物體驗,本項目開發了一個基于 Spring Boot Vue 技術棧的母嬰商城系統,實現了商品分類、商品瀏覽、資訊展示、評…

實戰演練:用 AWS Lambda 和 API Gateway 構建你的第一個 Serverless API

實戰演練:用 AWS Lambda 和 API Gateway 構建你的第一個 Serverless API 理論千遍,不如動手一遍!在前面幾篇文章中,我們了解了 Serverless 的概念、FaaS 的核心原理以及 BaaS 的重要作用。現在,是時候把這些知識運用起來,親手構建一個簡單但完整的 Serverless 應用了。 …

node.js 實戰——express圖片保存到本地或服務器(七牛云、騰訊云、阿里云)

本地 ? 使用formidable 讀取表單內容 npm i formidable ? 使用mime-types 獲取圖片后綴 npm install mime-types? js 中提交form表單 document.getElementById(uploadForm).addEventListener(submit, function(e){e.preventDefault();const blob preview._blob;if(!blob)…

2025最新:3分鐘使用Docker快速部署單節點Redis

🧑?🏫 詳細教程:通過 Docker 安裝單節點 Redis 🛠? 前提條件: 你需要在 Ubuntu 系統上進行操作(如果你在其他系統上操作,可以按相似步驟進行調整)。已安裝 Docker 和 Docker Com…

CentOS 7 系統下安裝 OpenSSL 1.0.2k 依賴問題的處理

前面有提到過這個openssl的版本沖突問題,也是在這次恢復服務器時遇到的問題,我整理如下,供大家參考。小小一個軟件的安裝,挺坑的。 一、問題 項目運行環境需要,指定PHP7.0.9這個版本,但是?系統版本與軟件…

LoRA(Low-Rank Adaptation)原理詳解

LoRA(Low-Rank Adaptation)原理詳解 LoRA(低秩適應)是一種參數高效微調(Parameter-Efficient Fine-Tuning, PEFT)技術,旨在以極低的參數量實現大模型在特定任務上的高效適配。其核心思想基于低秩分解假設,即模型在適應新任務時,參數更新矩陣具有低秩特性,可用少量參…

Solana批量轉賬教程:提高代幣持有地址和生態用戶空投代幣

前言 Solana區塊鏈因其高吞吐量和低交易費用成為批量操作(如空投)的理想選擇。本教程將介紹幾種在Solana上進行批量轉賬的方法,幫助您高效地向多個地址空投代幣。 solana 賬戶模型 在Solana中有三類賬戶: 數據賬戶,…

基于LSTM與SHAP可解釋性分析的神經網絡回歸預測模型【MATLAB】

基于LSTM與SHAP可解釋性分析的神經網絡回歸預測模型【MATLAB】 一、引言 在數據驅動的智能時代,時間序列預測已成為許多領域(如金融、氣象、工業監測等)中的關鍵任務。長短期記憶網絡(LSTM)因其在捕捉時間序列長期依…

手機網頁提示ip被拉黑名單什么意思?怎么辦

?當您使用手機瀏覽網頁時,突然看到“您的IP地址已被列入黑名單”的提示,是否感到困惑和不安?這種情況在現代網絡生活中并不罕見,但確實會給用戶帶來諸多不便。本文將詳細解釋IP被拉黑的含義、常見原因,并提供一系列實…

Java消息隊列性能優化實踐:從理論到實戰

Java消息隊列性能優化實踐:從理論到實戰 1. 引言 在現代分布式系統架構中,消息隊列(Message Queue,MQ)已經成為不可或缺的中間件組件。它不僅能夠實現系統間的解耦,還能提供異步通信、流量削峰等重要功能…

BUUCTF——Cookie is so stable

BUUCTF——Cookie is so stable 進入靶場 頁面有點熟悉 跟之前做過的靶場有點像 先簡單看一看靶場信息 有幾個功能點 flag.php 隨便輸了個admin 根據題目提示 應該與cookie有關 抓包看看 構造payload Cookie: PHPSESSIDef0623af2c1a6d2012d57f3529427d52; user{{7*7}}有…

json格式不合法情況下,如何盡量保證數據可用性

背景 在工作流程中,并非所有數據都如人所愿,即使json版本也會由于csv、tsv、excel、text等不同文件格式轉化、獲取數據源不完整等問題,造成我們要處理的json文件存在不合法。 嘗試方案 除了人為修正外,有效的方法是使用json“修…

Python基礎總結(十)之函數

Python函數 函數是Python中也是非常重要的,函數是帶名字的代碼塊,用于完成具體的工作。要執行函數定義的特定任務,可調用該函數。 一、函數的定義 函數的定義要使用def關鍵字,def后面緊跟函數名,縮進的為函數的代碼塊。 def test():print("Hello,World")上述…

懶人美食幫SpringBoot訂餐系統開發實現

概述 快速構建一個訂餐系統,今天,我們將通過”懶人美食幫”這個基于SpringBoot的訂餐系統項目,為大家詳細解析從用戶登錄到多角色權限管理的完整實現方案。本教程特別適合想要學習企業級應用開發的初學者。 主要內容 1. 用戶系統設計與實現…

AI(學習筆記第三課) 使用langchain進行AI開發(2)

文章目錄 AI(學習筆記第三課) 使用langchain進行AI開發(2)學習內容:1. 返回結構化數據(structured_output pydantic)1.1 使用背景1.2 返回結構化數據示例代碼(pydantic)1.3 執行測試代碼2 返回結構化數據(json)2.1 示例代碼2.2 執行結果3 給提供一些例子(few shot pr…

unity 使用藍牙通訊(PC版,非安卓)

BlueTooth in pc with unity 最近接到的需求是在unity里面開發藍牙功能,其實一開始我并不慌,因為據我所知,unity有豐富的插件可以使用,但是問題隨之而來 1.unity里面無法直接與藍牙通訊(后來找到了開啟runtime一類的東西,但是我找了半天也沒找到在哪里可以打開) 2.引入dll通過d…

MySQL中的意向鎖 + next-key鎖 + 間隙鎖

引言 在數據庫并發控制中,鎖機制是保障數據一致性和隔離性的核心手段。MySQL中意向鎖、間隙鎖以及next-key鎖等復雜鎖類型,旨在協調表級鎖與行級鎖之間的關系,防止數據的臟讀、不可重復讀和幻讀現象,尤其是在可重復讀隔離級別下發…

機器學習 數據集

數據集 1. scikit-learn工具介紹1.1 scikit-learn安裝1.2 Scikit-learn包含的內容 2 數據集2.1 sklearn玩具數據集介紹2.2 sklearn現實世界數據集介紹2.3 sklearn加載玩具數據集示例1:鳶尾花數據示例2:分析糖尿病數據集 2.4 sklearn獲取現實世界數據集示…

Linux-c語言串口程序

c語言串口程序 // C library headers #include <stdio.h> #include <string.h>// Linux headers #include <fcntl.h> // Contains file controls like O_RDWR #include <errno.h> // Error integer and strerror() function #include <termios.h&g…