成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C++中列表初始化,你知多少?

開發 前端
雖然列表初始化是一種很便捷和安全的初始化方式,但在某些情況下,特別是對于非聚合類型和可能導致 most vexing parse 的地方,可能需要考慮其他的初始化方式。

一、何為列表初始化

C++中的列表初始化是一種用一對花括號 {} 來進行對象初始化的語法。它被引入主要是為了提供一種統一的初始化方式,適用于各種不同的數據類型和數據結構,包括基本類型、數組、結構體、類、STL 容器等。列表初始化在 C++11 標準中被引入,是現代 C++ 編程風格的一部分。

基本語法

Type variable = {value1, value2, ...};
  • 使用一對花括號 {} 來初始化對象。
  • 列表初始化對于類型轉換更為嚴格,不允許縮窄轉換(請看下面何為窄轉化部分)。

示例

  • 基本類型:
int x = {42};
double y = {3.14};
  • 數組:
int arr[] = {1, 2, 3, 4, 5};
  • 結構體:
struct Point {
    int x;
    int y;
};

Point p = {10, 20};
  • 類:
class MyClass {
public:
    int data;
    double value;

    MyClass(int d, double v) : data(d), value(v) {}
};

MyClass obj = {42, 3.14};
  • STL 容器:
#include <vector>
#include <map>

std::vector<int> vec = {1, 2, 3, 4, 5};
std::map<int, std::string> myMap = {{1, "one"}, {2, "two"}};
  • 自定義類型:
class MyType {
public:
    int x;
    double y;

    MyType(int a, double b) : x(a), y(b) {}
};

MyType myVar = {5, 2.5};

二、何為窄轉化

窄轉化(Narrowing Conversion)指的是將一個具有較大范圍的值轉換為較小范圍的類型時可能丟失信息的情況。這種轉換可能導致截斷或失真,因為目標類型的表示范圍比源類型小。在 C++ 中,窄轉化是一種不安全的類型轉換,因為它可能導致數據丟失或意外的行為。

以下是一些示例說明窄轉化:

  • 從浮點數到整數:
double myDouble = 3.14;
int myInt = myDouble; // 窄轉化,可能會截斷小數部分
  • 從長整型到整數:
long long myLong = 1000000000000;
int myInt = myLong; // 窄轉化,可能會截斷或溢出
  • 從大范圍的整數類型到小范圍的整數類型:
long long myLong = 1000000000000;
int myInt = static_cast<int>(myLong); // 窄轉化,可能會截斷或溢出

窄轉化是需要小心處理的,因為它可能導致數據的損失和不確定的行為。在需要進行類型轉換時,最好使用安全的轉換方式,例如使用 static_cast 并在可能丟失信息的地方進行顯式的檢查和處理。在 C++11 引入的列表初始化中,提供了對縮窄轉換的更嚴格的檢查,不允許在列表初始化時發生縮窄轉換,從而幫助程序員避免潛在的問題。

三、列表初始化規則和特點

列表初始化有一些規則和特點,主要包括以下幾個方面:

1. 不允許縮窄轉換

列表初始化對類型轉換更為嚴格,不允許發生縮窄轉換,即不允許將一個精度更高的類型賦值給一個精度較低的類型。

int x = {3.14}; // 錯誤,嘗試縮窄轉換

2. 對于數組,列表初始化的大小由元素個數決定

int arr[] = {1, 2, 3}; // 合法,數組大小為3

3. 類型不匹配時可能調用構造函數

當列表初始化的類型和目標類型不匹配時,如果存在適當的構造函數,編譯器會嘗試調用構造函數進行初始化。

class MyClass {
public:
    int data;
    double value;

    MyClass(int d, double v) : data(d), value(v) {}
};

MyClass obj = {42, 3.14}; // 合法,調用構造函數

4. 空列表初始化

在某些情況下,可以使用空的花括號 {} 進行初始化,這會被解釋為對應類型的默認值。

int x = {}; // x 被初始化為 0
double y = {}; // y 被初始化為 0.0

5. 對于類類型,構造函數的匹配規則

當進行列表初始化時,編譯器會根據構造函數的參數匹配規則選擇相應的構造函數。

class Example {
public:
    Example(int a, double b);
    Example(std::string str);
};

Example obj1 = {42, 3.14};  // 調用構造函數 Example(int, double)
Example obj2 = {"Hello"};    // 調用構造函數 Example(std::string)

6. 嵌套初始化

可以使用嵌套的列表初始化來初始化嵌套的數據結構。

std::vector<std::vector<int>> matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

總體來說,列表初始化提供了一種簡潔且直觀的初始化語法,同時對類型匹配和轉換有著更為嚴格的規定,減少了一些初始化時可能發生的錯誤。

四、列表初始化的好處

列表初始化(Uniform Initialization)在 C++ 中引入的好處主要有以下幾點:

  • 一致性:列表初始化提供了一種一致的初始化語法,可以用于初始化各種類型的對象,包括基本類型、數組、結構體、類、STL 容器等。這種一致性使得代碼更加清晰和易讀。
int x = {42};             // 初始化基本類型
int arr[] = {1, 2, 3};    // 初始化數組
Point p = {10, 20};       // 初始化結構體
MyClass obj = {42, 3.14};  // 初始化類
std::vector<int> vec = {1, 2, 3}; // 初始化容器
  • 防止窄化轉換:列表初始化對類型轉換更為嚴格,不允許發生縮窄轉換,從而減少了一些可能引入 bug 的情況。
int x = {3.14}; // 錯誤,嘗試縮窄轉換
  • 構造函數匹配:當進行列表初始化時,如果存在適當的構造函數,編譯器會嘗試調用構造函數進行初始化。這提高了代碼的靈活性,使得用戶定義的類型更容易進行初始化。
class MyClass {
public:
    int data;
    double value;

    MyClass(int d, double v) : data(d), value(v) {}
};

MyClass obj = {42, 3.14}; // 調用構造函數
  • 簡潔性:列表初始化的語法相對簡潔,通過一對花括號{}就可以完成初始化,避免了傳統的各種初始化方式可能導致的歧義。
int arr[] = {1, 2, 3};  // 合法,簡潔
  • 避免 most vexing parse: 傳統的初始化語法在某些情況下可能會導致 most vexing parse,而列表初始化語法避免了這一問題。

"Most Vexing Parse" 是一個有趣而令人困擾的 C++ 編程問題,它通常發生在類的對象聲明上,導致程序員可能不是按照他們預期的方式初始化對象。這個問題的名字來源于這種情況的令人迷惑和難以理解。

Most Vexing Parse 主要發生在下面這樣的情況:

class MyClass {
public:
    MyClass() {}
};

int main() {
    MyClass obj();  // 最令人迷惑的解析,聲明了一個函數而不是對象
    // ...
    return 0;
}

在上述代碼中,MyClass obj(); 被編譯器解釋為聲明一個返回 MyClass 類型的函數而不是創建一個 MyClass 類型的對象。這是因為在 C++ 中,如果聲明一個函數的時候帶有空括號,編譯器會將其解釋為一個函數聲明而不是一個對象定義。

為了避免 most vexing parse,可以使用以下兩種方式之一:

  • 使用花括號初始化:
MyClass obj{};  // 使用花括號初始化,避免 most vexing parse
  • 使用括號初始化:
MyClass obj();  // 編譯器會將其解釋為函數聲明
MyClass obj{};  // 使用括號初始化,避免 most vexing parse

這個問題是由 C++ 語法規則引起的,對于初學者來說可能會令人困擾。因此,在聲明和初始化對象時,特別是在有可能發生 most vexing parse 的地方,建議使用花括號初始化或括號初始化,以避免潛在的問題。

五、不適用列表初始化的情況

什么是聚合類型

1、類型是一個普通數組,如int[5],char[],double[]等 

2、類型是一個類,且滿足以下條件:

  • 沒有用戶聲明的構造函數
  • 沒有用戶提供的構造函數(允許顯示預置或棄置的構造函數)
  • 沒有私有或保護的非靜態數據成員
  • 沒有基類
  • 沒有虛函數
  • 沒有{}和=直接初始化的非靜態數據成員
  • 沒有默認成員初始化器

雖然列表初始化是一種很方便和清晰的初始化方式,但有一些情況下不適合或者不能使用列表初始化:

  • 不支持聚合初始化的類列表初始化主要用于聚合類型的初始化,而對于不支持聚合初始化的類,不能使用列表初始化。一個類如果有用戶自定義的構造函數、私有/受保護的非靜態數據成員,或者基類沒有默認構造函數,那么該類就不再是聚合類型。
class NotAggregate {
public:
    int x;
    int y;

    NotAggregate(int a, int b) : x(a), y(b) {}
};

NotAggregate obj = {1, 2}; // 錯誤,NotAggregate 不是聚合類型
  • 不能進行窄化轉換的地方:列表初始化不允許發生窄化轉換,因此在需要執行窄化轉換的地方不能使用列表初始化。
double myDouble = 3.14;
int myInt = myDouble; // 合法,但列表初始化會報錯
  • 需要避免 most vexing parse 的地方:在可能發生 most vexing parse(最令人迷惑的解析)的地方,列表初始化可能不適用。這通常發生在類的默認構造函數被誤解為函數聲明的情況下。
class MyClass {
public:
    MyClass() {}
};

MyClass obj();   // 最令人迷惑的解析,聲明了一個函數而不是對象
MyClass obj{};   // 正確的初始化方式

總之,雖然列表初始化是一種很便捷和安全的初始化方式,但在某些情況下,特別是對于非聚合類型和可能導致 most vexing parse 的地方,可能需要考慮其他的初始化方式。

責任編輯:武曉燕 來源: Linux兵工廠
相關推薦

2023-11-12 23:08:17

C++初始化

2010-02-01 14:21:24

C++初始化列表

2020-10-12 09:49:14

C++ 開發代碼

2010-02-06 14:40:50

C++初始化和賦值

2023-10-06 20:57:52

C++聚合成員

2010-02-05 17:16:05

C++構造函數

2010-02-06 15:58:10

C++集合初始化

2011-06-09 14:13:06

C++JAVA缺省初始化

2011-06-17 15:29:44

C#對象初始化器集合初始化器

2024-08-08 16:34:16

C++11編程

2021-12-26 00:08:35

C++初始化列表

2010-02-03 11:01:18

C++類靜態成員初始化

2016-01-28 19:58:43

創業IT建設

2020-06-08 07:00:00

數據安全加密機密計算

2023-12-04 10:57:52

函數C++

2009-09-18 11:15:52

C#數組初始化

2009-07-31 17:51:27

C#對象初始化

2019-11-04 13:50:36

Java數組編程語言

2024-08-26 15:06:20

2010-02-06 10:24:48

C++二維數組初始化
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩中 | 久久www免费视频 | 一区视频在线免费观看 | 色资源在线 | 欧美亚洲综合久久 | 成人中文字幕在线 | 久久99精品久久久久久 | 天天射网站 | 欧美中文字幕在线观看 | 成人一区二区在线 | 福利精品 | 国产成人精品综合 | 99热都是精品 | 国产小u女发育末成年 | 一区二区精品电影 | 天天干夜夜操 | 国内精品久久久久久久 | 午夜小视频在线播放 | 九九99靖品 | 五月婷婷 六月丁香 | 可以免费观看的av片 | 自拍偷拍小视频 | 国产成人精品一区二三区在线观看 | 国产精品成人一区 | 欧美日韩中文字幕 | eeuss国产一区二区三区四区 | 国产精品成人一区 | 精品国产一区二区在线 | 91免费版在线观看 | 亚洲精品一区中文字幕乱码 | 国产精品国产自产拍高清 | 国产一区二区三区在线 | 亚洲国产免费 | 天堂av免费观看 | 在线看一区二区三区 | 一区二区三区在线免费看 | 视频在线观看一区二区 | 国产精品成人一区二区三区夜夜夜 | 天天射天天操天天干 | www国产亚洲精品久久网站 | 亚洲精品在线免费 |