文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-11-30 00:43

关注

基本语法

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};
#include 
#include 

std::vector vec = {1, 2, 3, 4, 5};
std::map 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(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> matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

总体来说,列表初始化提供了一种简洁且直观的初始化语法,同时对类型匹配和转换有着更为严格的规定,减少了一些初始化时可能发生的错误。

四、列表初始化的好处

列表初始化(Uniform Initialization)在 C++ 中引入的好处主要有以下几点:

int x = {42};             // 初始化基本类型
int arr[] = {1, 2, 3};    // 初始化数组
Point p = {10, 20};       // 初始化结构体
MyClass obj = {42, 3.14};  // 初始化类
std::vector vec = {1, 2, 3}; // 初始化容器
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" 是一个有趣而令人困扰的 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 的地方,建议使用花括号初始化或括号初始化,以避免潜在的问题。

五、不适用列表初始化的情况

什么是聚合类型

类型是一个普通数组,如int[5],char[],double[]等 

类型是一个类,且满足以下条件:

虽然列表初始化是一种很方便和清晰的初始化方式,但有一些情况下不适合或者不能使用列表初始化:

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; // 合法,但列表初始化会报错
class MyClass {
public:
    MyClass() {}
};

MyClass obj();   // 最令人迷惑的解析,声明了一个函数而不是对象
MyClass obj{};   // 正确的初始化方式

总之,虽然列表初始化是一种很便捷和安全的初始化方式,但在某些情况下,特别是对于非聚合类型和可能导致 most vexing parse 的地方,可能需要考虑其他的初始化方式。

来源:Linux兵工厂内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯