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

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

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

相关文章

后端工程师快速使用vue和Element

文章目录 Vue1 Vue概述2 快速入门3 Vue指令3.1 v-bind和v-model3.2 v-on3.3 v-if和v-show3.4 v-for3.5 案例 4 生命周期 Element快速使用1 Element介绍2 快速入门3 当前页面中嵌套另一个页面案例代码案例截图 Vue 1 Vue概述 通过我们学习的htmlcssjs已经能够开发美观的页面了…

从历年315曝光案例,看APP隐私合规安全

更多网络安全干货内容&#xff1a;点此获取 ——————— 随着移动互联网新兴技术的发展与普及&#xff0c;移动APP的应用渗透到人们的衣食住行方方面面&#xff0c;衍生出各类消费场景的同时&#xff0c;也带来了无数的个人隐私数据泄露、网络诈骗事件。 历年来&#xff…

FPGA——DDR3的IP核

FPGA——DDR3的ip核 IP核配置基于MIG核代码基于AXI接口的DDR3 IP核配置 1 2 3 4 5 6 基于MIG核代码 控制MIG核的信号进行读写 module MIG_APP_Drive(input i_ui_clk ,input i_ui_rst ,input init_calib_…

【SpringCloud】使用Seata实现分布式事务

目录 一、Seata 框架的需求背景二、Seata 事务模式与架构2.1 Seata 组成2.2 Seata 事务模式 三、Seata 实战演示3.1 部署 Seata Server3.1.1 下载 Seata Server3.1.2 更改 Seata Server 配置3.1.3 创建 Seata Server 所需的数据库、数据库表3.1.4 启动 Seata Server 3.2 Seata …

恒创科技:什么是BGP线路服务器?BGP机房的优点是什么?

在当今的互联网架构中&#xff0c;BGP(边界网关协议)线路服务器和BGP机房扮演着至关重要的角色。BGP作为一种用于在自治系统(AS)之间交换路由信息的路径向量协议&#xff0c;它确保了互联网上的数据能够高效、准确地从一个地方传输到另一个地方。那么&#xff0c;究竟什么是BGP…

vue中判断是否使用自定义插槽

在封装自定义组件时&#xff0c;需要判断使用者是否使用了插槽<slot"aaa">&#xff0c;如果没有则使用一个组件中默认的值&#xff0c;反之就用传入的内容<template name"aaa"></template>,实现如下&#xff1a; <div class"lin…

视频私有云,HDMI/AV多硬件设备终端接入,SFU/MCU视频会议交互方案。

在视频业务深入的过程中越来越多的硬件设备接入视频交互的视频会议中远程交互&#xff0c;有的是视频采集&#xff0c;有的是医疗影像等资料&#xff0c;都需要在终端承显&#xff0c;这就需要我们的设备终端能多设备&#xff0c;多协议接入&#xff0c;设备接入如下。 1&#…

【NTN 卫星通信】 TN和多NTN配合的应用场景

1 场景描述 此场景描述了农村环境&#xff0c;其中MNO (运营商TerrA)仅在城市附近提供本地地面覆盖&#xff0c;而MNO (SatA)提供广泛的NTN覆盖。SatA使用GSO轨道和NGSO轨道上的卫星。SatA与TerrA有漫游协议&#xff0c;允许:   所有TerrA用户的连接&#xff0c;当这些用户不…

Android FrameWork 学习路线

目录 前言 学习路线&#xff1a; 1.基础知识 2、AOSP 源码学习 3. AOSP 源码编译系统 4. Hal与硬件服务 5.基础组件 6. Binder 7. 系统启动过程分析 8. 应用层框架​编辑 9. 显示系统 10. Android 输入系统 11. 系统应用 前言 Android Framework 涉及的行业相当广…

行尾检测论文汇总

文章目录 2023GNSS-Free End-of-Row Detection and Headland Maneuvering for Orchard Navigation Using a Depth Camera 2023 GNSS-Free End-of-Row Detection and Headland Maneuvering for Orchard Navigation Using a Depth Camera 摘要&#xff1a; 果园中基于GPS的导航…

挖到宝了!这些内容管理平台是企业的最佳选择

内容管理系统&#xff0c;不再只是专业人士的语言&#xff0c;而是已经突破到普通人的视野中。简单易懂的解释就是&#xff0c;内容管理平台就像是一个大货仓&#xff0c;你可以在这里存储、整理和搜索你的所有资料。那么今天&#xff0c;我要向你推荐的是三款强大的内容管理平…

Kotlin进阶之协程从上车到起飞

公众号「稀有猿诉」 原文链接 Kotlin进阶之协程从上车到起飞 通过前面的一篇文章我们理解了协程的基本概念&#xff0c;学会协程的基本使用方法&#xff0c;算是正式入门了&#xff0c;接下来就是要深入的学习技术细节和高级使用方法&#xff0c;以期完全掌握Kotlin协程…

“SRP模型+”多技术融合在生态环境脆弱性评价模型构建、时空格局演变分析与RSEI 指数的生态质量评价及拓展应用教程

原文链接&#xff1a;“SRP模型”多技术融合在生态环境脆弱性评价模型构建、时空格局演变分析与RSEI 指数的生态质量评价及拓展应用教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247597452&idx5&snf723d9e5858a269d00e15dbe2c7d3dc0&chksmfa823c6…

SSA优化最近邻分类预测(matlab代码)

SSA-最近邻分类预测matlab代码 麻雀搜索算法(Sparrow Search Algorithm, SSA)是一种新型的群智能优化算法&#xff0c;在2020年提出&#xff0c;主要是受麻雀的觅食行为和反捕食行为的启发。 数据为Excel分类数据集数据。 数据集划分为训练集、验证集、测试集,比例为8&#…

代码随想录刷题day27|组合总和II组合总和II分割回文串

文章目录 day27学习内容一、组合总和-所选数字可重复1.1、代码-正确写法1.1.1、为什么递归取的是i而不是i1呢&#xff1f; 二、组合总和II-所选数字不可重复2.1、和39题有什么不同2.2、思路2.2.1、初始化2.2.2、主要步骤2.2.3、回溯函数 backTracking 2.3、正确写法12.3.1、为什…

四.排序(冒泡/选择)

目录 11-排序介绍 常见排序算法: 12-冒泡排序介绍 代码要求: 思路: 13-冒泡排序 代码: 14-选择排序 简单写法: 好的写法: 11-排序介绍 排序&#xff1a;将一组“无序”的记录序列调整为“有序”的记录序列。 列表排序&#xff1a;将无序列表变为有序列表 输入&#…

【数据结构与算法】:非递归实现快速排序、归并排序

&#x1f525;个人主页&#xff1a; Quitecoder &#x1f525;专栏&#xff1a;数据结构与算法 上篇文章我们详细讲解了递归版本的快速排序&#xff0c;本篇我们来探究非递归实现快速排序和归并排序 目录 1.非递归实现快速排序1.1 提取单趟排序1.2 用栈实现的具体思路1.3 代码…

java方法的引用传递和值传递

1、方法的值参数传递 下面代码&#xff0c;它会在控制台输出什么&#xff1f; public class ArrayTest {public static void main(String[] args) {int number 100;System.out.println(number);change(number);System.out.println(number);}public static void change(int n…

【力扣精选算法100道】——带你了解(数组模拟栈)算法

目录 &#x1f4bb;比较含退格的字符串 &#x1f388;了解题意 &#x1f388;分析题意 &#x1f6a9;栈 &#x1f6a9;数组模拟栈 &#x1f388;实现代码 844. 比较含退格的字符串 - 力扣&#xff08;LeetCode&#xff09; &#x1f4bb;比较含退格的字符串 &#x1f3…

Python--类中作用域

1、在面向对象编程中&#xff0c;主要的变量就是成员变量&#xff08;属性&#xff09;和局部变量 class Cat:# 属性name Noneage None# n1, n2, result为局部变量def cal(self, n1, n2):result n1 n2print(f"result{result}") 2、作用域的分类&#xff1a;属性…
最新文章