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

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++ 的初始化规则,我们可以编写出更安全、更清晰、更易于理解的代码,这将有助于我们更好地表达思想,解决问题。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HCIP —— 三层架构

企业网的三层架构 园区网络 常见的行业园区网 按照传输介质分类&#xff0c;可以将网络分为有线网络、无线网络和光纤网。 无线网络是有线网络的最后一公里。 无线网络 无线网络 --- Access Point --- 简称 AP --- 无线接入点 路由器上的WAN口:用于连接运营商的接口 路由器…

vue右键自定义样式

<!-- eslint-disable vue/no-dupe-keys --> <template><div><div class"search-box"><div class"search"><el-input placeholder"搜索" prefix-icon"el-icon-search" v-model"input2">…

STM32OLED调试工具

OLED介绍 4个引脚的oled &#xff1a; GND引脚接地&#xff0c;VCC接3.3v的电源 SCL与SDA是I2C通信的引脚 使用OLED显示屏驱动函数模块 接线图 将oled函数调试的代码引入到工程项目中 oled工程代码 OLED.C文件代码 #include "stm32f10x.h" #include "OLED_Font…

自定义方法SQL注入器-DefaultSqlInjector

/*** 自定义Sql注入* author zy*/ public class SqlInjector extends DefaultSqlInjector {Overridepublic List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {// 注意&#xff1a;此SQL注入器继承了DefaultSqlInjector(默认注入器…

Oracle 主从切换脚本

一、 切换前预检查 1. dg_precheck_main_v1.4.sh #!/bin/bash#********************************************************************************** # Author: Hehuyi_In # Date: 2022年06月16日 # FileName: dg_precheck_main_v1.4.sh # # For sys user, execute the sc…

2024年初中生古诗文大会备考:多选题真题和独家解析(持续更新)

今天我们继续来做初中古诗文大会的一道难题&#xff1a;多选题&#xff0c;让大家了解初中生古诗文大会的考察内容和形式&#xff0c;并且提供了我独家的题目解析和答案&#xff0c;供初中的同学们学习和参考。 Tips&#xff1a;古诗文大会的许多题目都来自于中考、高考&#…

goland设置保存文件时不将4个空格转为TAB

goland设置保存文件时不将4个空格转为TAB 版本&#xff1a;GoLand 2022.3 设置路径&#xff1a; Settings -> Editor -> Code Style -> Go -> Run gofmt图示&#xff1a;

springmvc学习笔记1

springmvc学习笔记part1 总概述图创建步骤创建project并在父工程中导入配置类添加为web工程检查maven配置写handller方法写配置类SpringMVC环境搭建项目部署关键步骤总结 具体设置路径设置注解接收参数&#xff08;重点param参数接收路径参数接收json参数接收请求头接收和cooki…

【Unity】persistentDataPath、streamingAssetsPath和dataPath

介绍 我们在用Unity进行开发时&#xff0c;资源路径是我们最常用到的&#xff0c;下面我就来简单介绍一下几种常用的路径。 1.dataPath dataPath是包含游戏数据文件夹的路径&#xff0c;是app程序包安装路径 Windows: xxx /Assets &#xff08;如下图&#xff09; Mac: xxx…

canvas绘制圆形进度条

canvas绘制圆形进度条 用canvas绘制了一个圆形进度条&#xff0c;记录一下&#xff1a; 效果如下&#xff1a; 感觉效果还行&#xff0c;不过有待优化 代码如下&#xff1a; 我是用Vue写的 组件的代码&#xff1a; progressCanvas.vue <template><div><can…

深度学习——基本数据类型创建Tensor(持续更新)

声明&#xff1a;本深度学习笔记基于课时18 索引与切片-1_哔哩哔哩_bilibili学习而来 All is about Tensor 定义&#xff1a;Tensors are simply mathematical objects that can be used to describe physical properties, just like scalars and vectors. In fact tensors a…

C语言黑魔法第三弹——动态内存管理

本文由于排版问题&#xff0c;可能稍显枯燥&#xff0c;但里面知识点非常详细&#xff0c;建议耐心阅读&#xff0c;帮助你更好的理解动态内存管理这一C语言大杀器 进阶C语言中有三个知识点尤为重要&#xff1a;指针、结构体、动态内存管理&#xff0c;这三个知识点决定了我们…

QT定时器使用

实现功能&#xff1a;在界面中显示日期跟时间&#xff0c;并时刻刷新 实现原理&#xff1a;定时器能反馈程序运行的时间&#xff0c;通过设定定时器的启动间隔可以实现对时间的更新 步骤&#xff1a; 1.设定两个QString分别获取系统当前的日期和时间&#xff0c;并导入到labl…

线性代数 --- 特征值与特征向量(下)

特征值与特征向量 Eigen Values & Eigen Vectors Part III:如何求解特征向量与特征值 The Key Equation 对于一般矩阵A&#xff0c;如何找到他的特征值与特征向量&#xff1f; Step I: Find λ first! 首先&#xff0c;我们有方程&#xff1a; 但这里有两个未知数&…

Git win与linux换行符转换的问题

转载&#xff1a;warning: in the working copy of ‘package-lock.json‘, LF will be replaced by CRLF the next time Git_warning: in the working copy of package.json, lf-CSDN博客 warning: in the working copy of ‘package-lock.json‘, LF will be replaced by CRL…

“人工智能+”成国策,天翼云如何打造大模型时代的驱动力样板?

文 | 智能相对论 作者 | 叶远风 两会政府工作报告中明确指出要制定支持数字经济高质量发展政策&#xff0c;开展“人工智能”行动&#xff0c;这意味着&#xff0c;“人工智能”已经成为国策。 在这种大背景下&#xff0c;大模型的重要性无疑被抬到了新的高度。 此时&#…

数据结构和算法:栈与队列

栈 栈 &#xff08;stack&#xff09;是一种遵循先入后出逻辑的线性数据结构 把堆叠元素的顶部称为“栈顶”&#xff0c;底部称为“栈底”。 将把元素添加到栈顶的操作叫作“入栈”&#xff0c;删除栈顶元素的操作叫作“出栈”。 栈的常用操作 /* 初始化栈 */ stack<int&g…

小明的背包——01背包问题

经典版 题目链接&#xff1a;1.小明的背包1 - 蓝桥云课 (lanqiao.cn) 01背包问题中&#xff0c;每种物品只有两种状态&#xff0c;即拿或不拿。设状态dp[i][j]max(dp[i-1][j],dp[i-1][j-w]v)&#xff1b;如果不拿物品i&#xff0c;那么最大价值就是dp[i-1][j]&#xff0c;如果…

Excel第26享:模糊查找之Hlookup函数与通配符的嵌套

1、需求描述 如下图所示&#xff0c;现第一行有三个参考值&#xff1a;人S、羊E、猪3&#xff0c;在第三行有5个字&#xff1a;马、牛、人、羊、猪&#xff0c;每个字如果出现在第一行的三个参考值中&#xff0c;就返回该单元格的数值。如&#xff0c;人&#xff0c;就返回“人…

Windows 应用商城无法打开,解决方法

Windows 应用商城无法打开&#xff0c;也会导致有些软件无法使用&#xff0c;比如动态主题无法更新。 解决方&#xff1a; 1、按windowsR键&#xff0c;输入inetcpl.cpl。确定。 2、Internet属性&#xff0c;高级&#xff0c;勾选“使用TLS1.1",“使用TLS1.2"。确定…