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

a,c,d 都是申明一个变量,a 非常easy理解就是申明一个变量,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类型,不可转换

最新文章

  1. Oracle---------sql 中取值两列中值最大的一列
  2. MySQL AHI 实现解析
  3. Android属性动画之ValueAnimation
  4. centos安装altas
  5. 官网服务质量检测脚本(源码来自《Python自动化运维实战》第二版刘天斯)
  6. pxe kickstart 配置+TFTP+NFS多版本系统部署
  7. dig out deledted chat messages
  8. CentOS安装Nginx安装详解
  9. Java基础知识强化之IO流笔记67:Properties的特殊功能使用
  10. composer php依赖管理工具
  11. OC之字符串 NSString与NSMutableString
  12. Tesseract 在 windows 下的安装及简单应用
  13. 【2018.10.11 C与C++基础】C Preprocessor的功能及缺陷(草稿)
  14. CSS高度塌陷问题解决方案
  15. 线程间操作无效: 从不是创建控件“button1”的线程访问它。
  16. C++单继承的构造函数和析构函数调用的顺序
  17. 菜鸟vimer成长记——第4.1章、通用插件
  18. Java学习笔记之:Struts2.0 环境搭建
  19. 【Maven】maven打包生成可执行jar文件
  20. 初次使用vue-cli3 来搭建项目

热门文章

  1. CISP/CISA 每日一题 四
  2. redirect_uri 参数错误
  3. PHP盛宴——经常使用函数集锦
  4. Linux系列-安装经常使用软件
  5. 浅析C#组件编程中的一些小细节
  6. j2ee,jsp,servlet文件下载server端
  7. 把java程序打包成.exe
  8. angular 响应式自定义表单控件—注册头像实例
  9. 谈谈我对P2P网络借贷的一些看法
  10. jquery常用方法总结(转)