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

news2024/11/15 11:16:49

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

目录

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

2.类成员初始化列表

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

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

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

6.代码块(作用域)

7.定义Lambda函数(Lambda Expressions)

8.总结


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

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

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

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

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

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

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

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

2.类成员初始化列表

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

class MyClass {
public:
    MyClass(int x, int y) : a{x}, b{y} {}
private:
    int a, b;
};

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

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

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

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

class CMyTestClassA
{
public:
	CMyTestClassA(int i = 0)
		: m_i{ i } {
		//1
	}
private:
	int m_i;
};

class CMyTestClassAHelper1
{
public:
	CMyTestClassAHelper1() : m_a{ 100 } {
		//2
	}
private:
	CMyTestClassA m_a;
};

class CMyTestClassAHelper2
{
public:
	CMyTestClassAHelper2() {
		m_a = { 100 };//3
	}
private:
	CMyTestClassA m_a;
};

int main()
{
    CMyTestClassAHelper1 m;
	CMyTestClassAHelper2 n;
    return 0;
}

        定义变量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 及以后版本)

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

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

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

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

std::vector<int> vec = {44,5,99};
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)

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

enum myEnum {
  Opt1,
  Opt2,
  Opt3
};

//C++11之后版本可以加class,限制枚举的作用域,如:
enum class myEnum {
  Opt1,
  Opt2,
  Opt3
};

6.代码块(作用域)

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

void exampleFunction()
{
    int x = 10;
    {
        int y = 20; // 局部变量 y 只在此代码块内可见
    }
    // y 在这里不可见
}

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

void TimeWheelScheduler::Stop() {
  {
    std::lock_guard<std::mutex> lock(mutex_);
    stop_ = true;
    //当lock离开这个作用域时,它会自动调用mutex_的unlock
  }

  thread_.join();
}

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

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

7.定义Lambda函数(Lambda Expressions)

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

auto lambda = [](int x) {
    return x * x;
};

8.总结

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1515988.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

js判断对象是否有某个属性

前端判断后端接口是否返回某个字段的时候 <script>var obj { name: "John", age: 30 };console.log(obj.hasOwnProperty("name")); // 输出 trueconsole.log(obj.hasOwnProperty("email")); // 输出 falselet obj11 { name: "Joh…

一文搞懂多模态:BeiT-3之前的14个多模态+4个周边原理解读

在人工智能的世界里&#xff0c;多模态学习不断地展现出其重要性。这个领域的迅速发展不仅促进了不同类型数据之间的深度融合&#xff0c;还为机器理解世界提供了更加丰富和细腻的视角。随着科技的不断演进&#xff0c;人工智能模型已经开始渐渐具备处理和理解从文本、图像&…

MySQL主从复制的原理

MySQL 主从复制是一种数据复制技术&#xff0c;用于在多个数据库服务器之间的数据同步。在主从复制架构中&#xff0c;一个服务器被设置为主服务器&#xff0c;充当数据源&#xff0c;其他服务器被设置为从服务器&#xff0c;用来复制主服务器的数据。 1.主从复制优点 主从复…

Unity Timeline学习笔记(3) - SignalTrack信号轨道和自定义带参数的Marker信号和轨道

信号轨道&#xff0c;顾名思义就是运行到某处发送一个信号。 普通用法 普通用法就是没有任何封装的&#xff0c;个人感觉特别难用&#xff0c;但是有必要理解一下工作原理。 添加信号 我们添加一个信号资源 生成后可以看到资源文件&#xff0c;这个是可以拖到SignalTrack上…

web 服务搭建

实验拓扑图&#xff1a; 实验环境搭建 Centos7-5作为Client&#xff08;12.0.0.12/24&#xff09;&#xff1b;Centos7-1作为网关服务器&#xff08;配置两块网卡ens33 192.168.246.7/24&#xff0c;ens36 12.0.0.1/24&#xff09;&#xff1b;Centos7-2作为Web1&#xff08;19…

2024年云仓酒庄深惠公司发布会圆满落幕:共襄盛举,携手共赢

原标题&#xff1a;2024年云仓酒庄深惠公司发布会圆满落幕&#xff1a;共襄盛举&#xff0c;携手共赢 随着岁月的流转&#xff0c;云仓酒庄以其卓越的品质和不懈的创新精神&#xff0c;在葡萄酒行业中独树一帜。2024年&#xff0c;云仓酒庄再次迎来了一场盛大的发布会——深惠…

一文读懂『归并排序』算法(Merge Sort)

目录 归并排序算法&#xff08;Merge Sort&#xff09;简介 算法基本思想和流程&#xff08;时间复杂度O(nlogn) &#xff09; ​编辑代码实现 归并排序模板&#xff08;背诵&#xff09; 归并排序算法&#xff08;Merge Sort&#xff09;简介 归并排序&#xff08;Merge …

MyBatis入门(JDBC规范,MyBatis,连接池,Lombok)【详解】

目录 一、JDBC规范【了解】 1. JDBC介绍 2. JDBC示例 3. JDBC的问题 二、MyBatis入门【重点】 1. Mybatis是什么 2. Mybatis使用步骤 3. Mybatis入门案例 1.创建SpringBoot工程 2.创建Mapper 3.功能测试 三、连接池【了解】 1. 什么是连接池 2. 有哪些数据库连接池…

Java_9最大连续1的个数

最大连续1的个数 给定一个二进制数组 nums &#xff0c; 计算其中最大连续 1 的个数。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,0,1,1,1] 输出&#xff1a;3 解释&#xff1a;开头的两位和最后的三位都是连续 1 &#xff0c;所以最大连续 1 的个数是 3. 示例 2: 输入…

SIP-7043 SV-7043网络吸顶喇叭商场会议室播放器10W网络有源吸顶喇叭

SIP-7043 SV-7043网络吸顶喇叭商场会议室播放器 10W网络有源吸顶喇叭 一、描述 SIP-7043是我司的一款SIP网络有源吸顶喇叭&#xff0c;具有10/100M以太网接口&#xff0c;内置有一个高品质扬声器&#xff0c;将网络音源通过自带的功放和喇叭输出播放&#xff0c;可达到功率1…

Ubuntu23.10安装FFmpeg及编译FFmpeg源码

安装FFmpeg: 打开终端: 输入 sudo apt install ffmpeg 安装成功: 验证FFmpeg 默认安装位置与库与头文件位置 使用FFmpeg源码编译: 1.安装YASM sudo apt-get install yasm

STM32 晶振(用示波器测RCC频率是否一致)

如果测出的频率不准确&#xff0c;可以修改一下看看是否有改善&#xff1a;

1. 用两种方式在springboot项目中实现适配器模式

文章目录 用两种方式在springboot项目中实现适配器模式1. 场景2. 方式1&#xff0c;通过实现类定义类型字段实现2.1 创建接口2.2 创建mysql实现类2.3 创建oracle实现类2.4 创建接口,在接口中注入service集合&#xff0c;根据每个实现类中定义的dbType进行匹配后进行调用2.5 测试…

个人博客系列-后端项目-用户注册功能(7)

介绍 用户注册API的主要流程&#xff1a;1.前端用户提交用户名&#xff0c;密码 2. 序列化器校验用户名&#xff0c;密码是否合法。3.存入数据库。4.签发token 创建序列化器 from rest_framework import serializers from rest_framework_simplejwt.serializers import Toke…

harmonyOS简介及背景

harmonyOS的场景模式18n: 1&#xff08;入口手机&#xff09;8&#xff08;电脑、VR、手环、iPad、智慧屏、&#xff09;–wifi—n(车载、智能家居等所有)harmonyOS不需要考虑软硬件的差异&#xff0c;是一个兼容N种的超级终端harmonyOS干了两件事&#xff1a; &#xff08;1&a…

前端项目,个人笔记(一)【定制化主题 + 路由设计】

目录 1、项目准备 1.1、项目初始化 1.2、elementPlus按需引入 注&#xff1a;使用cnpm安装elementplus及两个插件&#xff0c;会报错&#xff1a;vueelement-plus报错TypeError: Cannot read properties of null (reading isCE ) &#xff0c;修改&#xff1a; 测试&#…

[Redis]——Redis持久化的两种方式RDB、AOF

目录 RDB快照模式 概念&#xff1a; 触发时机&#xff1a; 异步做快照 AOF追加模式 概念&#xff1a; 触发时机&#xff1a; bgrewriteaof命令&#xff1a; 比较两种模式&#xff1a; RDB快照模式 概念&#xff1a; RDB模式就是保存当前Redis的状态到本地磁盘文件&am…

阿里云服务器ECS--安全,稳定,购买灵活,低成本

阿里云服务器ECS英文全程Elastic Compute Service&#xff0c;云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务&#xff0c;阿里云提供多种云服务器ECS实例规格&#xff0c;如ECS经济型e实例、通用算力型u1、ECS计算型c7、通用型g7、GPU实例等&#xff0c;阿里云服务器网al…

【Redis】Redis常用命令一

1.keys&#xff1a;返回所有满足条件的key&#xff0c;比如&#xff1a; KEYS pattern时间复杂度&#xff1a;O(N)&#xff0c;返回值&#xff1a;匹配pattern的所有key。 • h?llo 匹配 hello , hallo 和 hxllo • h*llo 匹配 hllo 和 heeeello • h[ae]llo 匹配 hello 和 …

Java基于微信小程序的校园生活互助小助手

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…