首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 初始化列表深度解析:四大必用場景與效率優勢

     編輯:關於C++

兩種初始化方式對比

class Animal {
    int weight, height;
public:
    // 方式 A:初始化列表(推薦)
    Animal(int w, int h) : weight(w), height(h) {}
    
    // 方式 B:構造函數體賦值
    Animal(int w, int h) { weight = w; height = h; }
};

對內建類型(int、指針等)無性能差異,但方式 A 更統一、可用於所有場景。

四大必須使用初始化列表的場景

1. 基類無默認構造函數

class Animal {
public:
    Animal(int w, int h) : weight(w), height(h) {}  // 無 Animal()
private:
    int weight, height;
};

class Dog : public Animal {
public:
    // 必須在初始化列表調用基類構造
    Dog(int w, int h, int t) : Animal(w, h), type(t) {}
private:
    int type;
};

對象構造順序:基類 → 成員 → 派生類。基類構造必須在派生類構造體前完成。

2. const 成員常量

class Dog {
    const int LEGS = 4;  // C++11 類內初始化
    // 或
    const int LEGS;
    Dog() : LEGS(4) {}  // 必須在初始化列表初始化
};

const 成員不可賦值,只能初始化。

3. 引用成員

class Dog {
    int& ref;  // 必須綁定初始化
    Dog(int& r) : ref(r) {}
};

4. 類類型成員(避免雙重構造)

class Food {
public:
    Food(int t=10) : type(t) { cout << "Food構造\n"; }
    Food(const Food&) { cout << "Food拷貝構造\n"; }
    Food& operator=(const Food&) { cout << "Food賦值\n"; return *this; }
private:
    int type;
};

class Dog {
    Food food;
public:
    // 方式 A:初始化列表 → 直接拷貝構造
    Dog(const Food& f) : food(f) { cout << "Dog構造A\n"; }
    
    // 方式 B:構造函數體賦值 → 默認構造 + 賦值
    Dog(const Food& f) { food = f; cout << "Dog構造B\n"; }
};

效率差異:方式 A 一次拷貝構造;方式 B 一次默認構造 + 一次賦值運算符。對複雜類型差距巨大。

初始化順序規則

成員初始化順序僅取決於類中聲明順序,與初始化列表書寫順序無關!

class Bad {
    int a, b;
    Bad(int x) : b(x), a(b) {}  // 危險!a 用 b 初始化,但 a 先聲明 → a 先初始化 → 讀取未初始化的 b
};

最佳實踐:初始化列表順序與聲明順序一致,開啟編譯器警告(-Wreorder)。

C++11 聚合初始化與列表初始化

struct Point { int x, y; };
Point p1{1, 2};           // 列表初始化
Point p2 = {1, 2};        // 同前
vector v = {1,2,3};  // 初始化列表構造

總結:何時用初始化列表?

場景必須用列表?建議
內建類型成員否統一風格用列表
基類無默認構造是必須
const/引用成員是必須
類類型成員否強烈建議(避免默認構造+賦值)
成員相互依賴視情況注意聲明順序
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved