首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

C/C++中{}的用法总结(全)

  • 25-02-17 10:20
  • 2058
  • 13266
blog.csdn.net

C++基础专栏:http://t.csdnimg.cn/UjhPR

相关系列文章

C++之std::initializer_list详解-CSDN博客

目录

1.定义初始化列表(Initializer List)

2.类成员初始化列表

3.无默认构造函数的类的默认初始化(C++11 及以后版本)

4.初始化器列表构造函数(C++11 及以后版本)

5.定义枚举类型(Enum Types)

6.代码块(作用域)

7.定义Lambda函数(Lambda Expressions)

8.总结


1.定义初始化列表(Initializer List)

        列表初始化是一种全新的初始化方式,它可以用于任何类型的对象,包括基本类型、数组、结构体和类。

        例如,下面的 C++ 代码展示了如何使用列表初始化:

  1. int a[]{1, 3, 5, 77, 78}; //使用列表初始化初始化数组
  2. int arr[] = {1, 2, 3, 4, 5}; // 初始化整数数组
  3. std::vector<int> vec = {10, 20, 30}; // 初始化整数向量
  4. struct Point { int x, y; };
  5. Point p = {5, 7}; // 初始化结构体
  6. int b{2352}; //初始化变量

在编程中,窄化转换是一种常见的问题。窄化转换是指一种可能丢失信息的转换,例如从浮点数转换到整数或从大整数转换到小整数。列表初始化可以帮助我们避免这种转换。

例如,下面的代码尝试用一个浮点数初始化一个整数:

int c{ 8.52 }; //编译错误

这段代码无法编译,因为 {8.52} 试图将浮点数转换为整数,这是一种窄化转换。通过这种方式,我们可以在编译时检测到这种可能的错误,防止数据丢失。

2.类成员初始化列表

在类的构造函数中,花括号可以用于成员初始化列表。

  1. class MyClass {
  2. public:
  3. MyClass(int x, int y) : a{x}, b{y} {}
  4. private:
  5. int a, b;
  6. };

在这个例子中,MyClass的构造函数使用列表初始化来初始化 a, b。这就保证了 MyClass在对象创建时总是被正确地初始化。

使用列表初始化来初始化类的成员变量有几个好处。

1)它可以避免成员变量的未初始化。如果我们忘记在构造函数中初始化一个成员变量,那么这个成员变量的值就会是未定义的,这可能会引发各种难以预测的问题。使用列表初始化可以确保成员变量总是被初始化,即使我们忘记在构造函数中初始化它。

2)提高效率。成员初始化列表在对象创建时直接初始化成员变量,而不是先创建成员变量,然后再为其赋值。这意味着使用成员初始化列表通常比在构造函数体内为成员变量赋值更高效。例如:

  1. class CMyTestClassA
  2. {
  3. public:
  4. CMyTestClassA(int i = 0)
  5. : m_i{ i } {
  6. //1
  7. }
  8. private:
  9. int m_i;
  10. };
  11. class CMyTestClassAHelper1
  12. {
  13. public:
  14. CMyTestClassAHelper1() : m_a{ 100 } {
  15. //2
  16. }
  17. private:
  18. CMyTestClassA m_a;
  19. };
  20. class CMyTestClassAHelper2
  21. {
  22. public:
  23. CMyTestClassAHelper2() {
  24. m_a = { 100 };//3
  25. }
  26. private:
  27. CMyTestClassA m_a;
  28. };
  29. int main()
  30. {
  31. CMyTestClassAHelper1 m;
  32. CMyTestClassAHelper2 n;
  33. return 0;
  34. }

        定义变量m在2处利用初始化列表构造初始化了m_a,在1处调用了一次CMyTestClassA的构造函数。
        定义变量n在3处看似只写了一行代码m_a={100}, 殊不知这个地方实际上初始化了两次m_a, 第一次是利用初始化列表构造初始化了m_a,这个和m的m_a构造差不多; 第二次是m_a = { 100 },
这里赋值又调用了一次构造函数,实际上在3处调用了两次构造函数; 在类比较简单的时候,多走一遍构造流程算不了什么; 在类比较复杂的时候,就会严重影响程序的执行效率,多次初始化,也有可能给程序带来一些未知的影响。

3.无默认构造函数的类的默认初始化(C++11 及以后版本)

对于没有默认构造函数的类,花括号可以用于默认初始化。

  1. class NoDefaultConstructor {
  2. public:
  3. NoDefaultConstructor(int x) { /* constructor code */ }
  4. };
  5. NoDefaultConstructor a = {1000}; // 使用初始化列表构造函数

4.初始化器列表构造函数(C++11 及以后版本)

花括号可以用于调用初始化器列表构造函数,这在创建对象时非常有用。

  1. std::vector<int> vec = {44,5,99};
  2. std::map<int, std::string> myMap = {{1, "one"}, {2, "two"}};

之所以std::vector、std::map等容器可以用{}构造,那是因为有std::initializer_list的存在。std::initializer_list在中间起了一个桥梁的作用,{}表达式、std::initializer_list和容器构造之间的转换流程如下图所示:

std::initializer_list的用法可参阅我的另外一篇博客:

深入理解可变参数(va_list、std::initializer_list和可变参数模版)-CSDN博客

5.定义枚举类型(Enum Types)

{} 可以用于定义枚举类型,其中包含一组可能的值。例如:

  1. enum myEnum {
  2. Opt1,
  3. Opt2,
  4. Opt3
  5. };
  6. //C++11之后版本可以加class,限制枚举的作用域,如:
  7. enum class myEnum {
  8. Opt1,
  9. Opt2,
  10. Opt3
  11. };

6.代码块(作用域)

        花括号用于创建代码块,也就是一个作用域。在一个代码块中,可以定义局部变量,控制变量的作用范围,以及变量的生命周期。代码块可以在函数、条件语句、循环语句等地方使用。如:

  1. void exampleFunction()
  2. {
  3. int x = 10;
  4. {
  5. int y = 20; // 局部变量 y 只在此代码块内可见
  6. }
  7. // y 在这里不可见
  8. }

很多时候{}代码块配合RAII自动释放资源。如下:

  1. void TimeWheelScheduler::Stop() {
  2. {
  3. std::lock_guard lock(mutex_);
  4. stop_ = true;
  5. //当lock离开这个作用域时,它会自动调用mutex_的unlock
  6. }
  7. thread_.join();
  8. }

在这个例子中,当lock离开其作用域时,std::lock_guard的析构函数会被调用,从而释放锁对象mutex_。这种自动管理锁方式避免了手动调用unlock可能导致的错误。

C++惯用法之RAII思想: 资源管理-CSDN博客

7.定义Lambda函数(Lambda Expressions)

{} 可以用于定义Lambda函数。Lambda函数是一种匿名的函数对象,可以在函数中传递。例如:

  1. auto lambda = [](int x) {
  2. return x * x;
  3. };

8.总结

        在 C++ 中,我们建议尽可能使用列表初始化(即大括号 {})。这种初始化方式可以提供更一致的语法,防止窄化转换,避免 “最令人困惑的语法” 问题,还可以用于初始化任何类型的对象,包括基本类型、数组、结构体,以及类的成员变量。此外,我们还应该养成总是初始化变量的习惯,以避免未初始化的变量引发的未定义行为。

        通过掌握 C++ 的初始化规则,我们可以编写出更安全、更清晰、更易于理解的代码,这将有助于我们更好地表达思想,解决问题。

注:本文转载自blog.csdn.net的流星雨爱编程的文章"https://blog.csdn.net/haokan123456789/article/details/136698925"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top