c++11之初始化列表

2023-05-16

一、前言
     C++的学习中,我想每个人都被变量定义和申明折磨过,比如我在大学笔试过的几家公司,都考察了const和变量,类型的不同排列组合,让你区别有啥不同。反正在学习C++过程中已经被折磨惯了,今天再来看看重温下那段“辉煌的历史”。先来看一段代码:
    Player pa;                              // (a)
    Player pb();                            // (b)
    Player pc = Player();                   // (c)  
    Player pd(Player());                    // (d)    
    pd = Player()                           // (e)


a,c,d 都是申明一个变量,a 很容易理解就是申明一个变量,b第一感觉是调用构造函数来申明变量,其实不是,而是申明一个无参数,返回Player的函数。对于c以为是调用了operator= 赋值运算吧?完全不是,而是先生成一个对象,然后调用Player的拷贝构造函数,生成对象pc。d和c是一样的。e才是真正调用赋值操作。是不是已经被这各式各样的对象申明搞的晕头专向了。现在C++11初始化列表正式登场。
二、简介
     在看C++11初始化前,先来回忆一下C语言中的结构体初始化,代码如下:
#include <iostream>

struct Player{
    int id;
    const char* name;
};

int main() {
    Player player = {10001, "c++"};
    printf("%d, %s\n", player.id, player.name);
}

     结构体变量可以列表初始化,非常方便。C++11引入了初始化列表来初始化变量和对象。
三、如何使用

     1、系统内置类型

    int ia{1};                // (a)
    int ib = {1};             // (b)   
    int ic(1);                // (c) 
    int id = 1;               // (d)

    很明显,还是d 更符合习惯。
    std::vector<int> va{1, 2, 3};          // (a)
    std::vector<int> vb = {1, 2, 3};       // (b)    
    std::vector<int> vc(1, 10);            // (c)   
    std::vector<int> vd{1, 10};            // (d)  
 
    通过初始化列表可以弥补c中只能初始化相同数字的问题。在使用中c和d不要混淆了。
    std::pair<int, const char*> getPlayer() {
         return {10001, "c++"};
     }
    std::map<int, const char*> players = {{10001, "c++"}, {10002, "java”}};
    
    还可以返回pair类型,初始化map都是可以的。

    2、自定义类型
    对于单个参数初始化,类型匹配构造函数,不需要自定义构造函数。
    Player pa{};                    // (a)
    Player pb;                      // (b)  
    Player pc();                    // (c)
    Player pd(b);                   // (d)
    Player pe = b;                  // (e)
    Player pf = {b};                // (f)



    对于上面几种变量初始化,推荐a, 如果是带参数的构造函数,推荐b,若果是不带参数的构造函数。

     3、如果是自己想实现初始化列表构造函数,拷贝函数,赋值函数,需要包含initializer_list 这个头文件。
class MyClass{
public:
    MyClass(int a):a_(a){
        std::cout << "normal initializer list\n";
    }

    MyClass(std::initializer_list<int> a):b_(a) {
        std::cout << "initializer list constructor\n";
    }

    MyClass(MyClass& my) {
        std::cout << "copy constructor\n";
        this->a_ = my.a_;
        this->b_ = my.b_;
    }

    MyClass& operator=(MyClass& my) {
        std::cout << "operator = constructor\n";
        this->a_ = my.a_;
        this->b_ = my.b_;
        return *this;
    }
private:
    int a_;
    std::initializer_list<int> b_;
};


这是自定义类,带有初始化列表构造函数的类,下面来练习下学过的类相关C++知识:
    MyClass ma{1};               // (a)
    MyClass mb = {1, 2, 3};      // (b)
    MyClass mc(2);               // (c)
    MyClass md = b;              // (d)
    MyClass me(c);               // (e)
    MyClass mf{e};               // (f)
    auto l{2, 2, 3,3};
    MyClass mh{l};               // (e)
    ma = mb;                     // (h)



看一下每次调用都输出什么结果,答案在这里:

initializer list constructor

initializer list constructor

normal constructor list

copy constructor

copy constructor

copy constructor

initializer list constructor

operator = constructor


四、为啥需要初始化列表
1、避免类申明对象混淆,区分对待,对于C++为啥有小括号初始化对象这一说,大家可以自行google,看来不管是谁都有犯错误的时候,勇于承认错误还是好同志。
2、在初始化多个变量时方便
3、避免数据切割,因为通过初始化列表是不允许隐式转换的,相关知识可以参考我的 这篇文章

五、注意事项
1、在申明变量的时候,少用小括号,程序可读性更高
2、使用初始化列表防止隐式转换,减少bug
3、通过 {} 返回的对象是const类型,不可转换
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++11之初始化列表 的相关文章

随机推荐

  • LARVIO 安装并运行

    LARVIO 安装并运行 LARVIO是基于MSCKF框架开发的一款实时SLAM xff0c 具体开源代码 xff1a https github com PetWorm LARVIO 1 依赖 1 1 Ubuntu and ROS 环境为U
  • MSCKF_VIO算法框架

    SCKF VIO算法 1 MSCKF视觉惯性融合算法简介 惯性导航利用惯性测量单元 IMU 测量得到的角速度 加速度信息进行惯性导航解算得到运载体的位置 速度 姿态 含航向 等信息 xff0c 具有实时性好 动态性能好等优点 xff1b 但
  • First Estimate Jacobian (FEJ) 如何理解SLAM中的First Estimate Jacobian

    First Estimate Jacobian FEJ 如何理解SLAM中的First Estimate Jacobian First Estimate Jacobian是Visual Inertial中的一个很重要的概念 xff0c 今天
  • 移动开发者大会--除了App,软件,我们还应该考虑什么

    今天有幸参加 移动者开发大会 xff0c 也是我第二次参与这个活动了 随着智能机的普及 xff0c 尤其是安卓千元的手机迅猛发展 xff0c 2011年可以说事移动领域的积累期 xff0c 2012年将会是蓬勃的发展期 各大厂商也在努力学习
  • 野火的freeRTOS工程怎么移植到正点原子上

    目录 简介 xff1a 时钟 xff1a 串口波特率设置问题 xff1a 滴答时钟的中断的时长问题 xff1a 简介 xff1a 正点原子的freeRTOS教程和野火系列的对比跟玩一样 xff0c 教的不细致 xff0c 代码注释也还没有野
  • ORB特征点提取代码详解 四叉树均匀化

    ORB特征点提取代码详解 ExtractORB 最近在尝试将ORB提取特征点机制放置于芯片上 xff0c 便于后期调用 xff0c 减小CPU的计算负担 xff0c 故最近对ORB特征点提取代码进行了研读 xff0c 记录一下 xff0c
  • Docker 使用教程

    Docker 使用教程 1 基本使用教程 使用docker docker 下载镜像 span class token function sudo span span class token function docker span pull
  • os.popen os.system subprocess shutil区别

    os popen os system subprocess shutil 区别 最近由于工作需求接触python xff0c 记录下遇到的问题 1 os popen os system 的区别 xff1a 总结 xff1a os popen
  • json与pickle相同和区别

    json与pickle相同和区别 1 json是可以在不同语言之间交换数据的 xff0c 而pickle只在python之间使用 2 json只能序列化最基本的数据类型 xff0c 而pickle可以序列化所有的数据类型 xff0c 包括类
  • 【id:58】【20分】C. 复数运算(友元函数)

    时间限制 1s 内存限制 128MB 题目描述 复数类的声明如下 xff1a class Complex private double real 实部 double imag 虚部 public Complex Complex double
  • Melodic + Realsense D435i 配置及错误问题解决

    Melodic 43 Realsense D435i 配置及错误问题解决 安装环境 xff1a RealSense SDK安装1 克隆SDK2 安装相关依赖3 安装权限脚本4 进行编译与安装5 测试安装是否成功6 错误汇总0x01 进行编译
  • Realsense-Ros安装配置介绍与问题解决

    Realsense Ros安装配置介绍与问题解决 Realsense Ros安装配置功能包克隆与编译编译错误与问题分析解决方案 结束语 本文主要讲述在如何进行Realsense Ros的安装与配置 xff0c 以及提出在安装配置过程中遇到相
  • 树莓派3 Ubuntu Meta16.04 操作系统烧录教程及系统换源

    树莓派3 Ubuntu Meta16 04 操作系统烧录教程及系统换源 1 写在开头 xff1a 2 操作系统烧录软件下载3 Ubuntu Meta 操作系统下载4 操作系统烧录4 1 SD 存储卡格式化4 2 操作系统写入4 3 换源更新
  • Ubuntu nautilus 快速打开文件浏览器

    Ubuntu nautilus 快速打开文件浏览器 1 问题描述2 nautilus 命令说明3 bashrc 下使用 alias 创建命令别名Reference 测试时间 xff1a 2022年6月20日 测试平台 xff1a Ubunt
  • 结构体嵌套结构体,及其的初始化

    作用 xff1a 结构体的的参数成员包含另一个结构体 利用 操作符来逐级访问结构体中的元素 1 先来个普通的结构体嵌套 xff0c xff08 不涉及数组 xff09 span class token macro property span
  • Spark Streaming + Spark SQL 实现配置化ETL流程

    Spark Streaming 非常适合ETL 但是其开发模块化程度不高 xff0c 所以这里提供了一套方案 xff0c 该方案提供了新的API用于开发Spark Streaming程序 xff0c 同时也实现了模块化 xff0c 配置化
  • 程序员永远的痛之字符编码的奥秘

    字符编码相信是每个程序员的噩梦 xff0c 只要是有中文的地方 xff0c 总是会遇到各种编码的问题 xff0c 并且这种问题还非常难缠 xff0c 尤其在linux上 xff0c 因为上面很多软件都是针对英语国家开发的 xff0c 是不会
  • 2013年终总结

    年终感悟 xff1a 2013年就这样过去了 xff0c 每个人都一样 xff0c 使用了自己一年生命药水 xff0c 要知道这种药品是花多少钱都买不来的 现在回头看看 xff0c 我用这一瓶药水都做了那些事情 在这一年里 xff0c 有过
  • C++11 之for 新解

    前言 C 43 43 11这次的更新带来了令很多C 43 43 程序员期待已久的for range循环 xff0c 每次看到javascript xff0c lua里的for range xff0c 心想要是C 43 43 能有多好 xff
  • c++11之初始化列表

    一 前言 C 43 43 的学习中 xff0c 我想每个人都被变量定义和申明折磨过 xff0c 比如我在大学笔试过的几家公司 xff0c 都考察了const和变量 xff0c 类型的不同排列组合 xff0c 让你区别有啥不同 反正在学习C