原文链接 https://www.cnblogs.com/dishengAndziyu/p/10906081.html

参考链接:https://www.cnblogs.com/laiqun/p/5776212.html

https://blog.csdn.net/zzyczzyc/article/details/87542418

https://www.cnblogs.com/cthon/p/9178701.html

http://blog.sina.com.cn/s/blog_4c79cc450100lkzh.html

1,初始化列表是在 C++ 中才引入的;

2,以“类中是否可以定义 const 成员?”这个问题来引入初始化列表:

1,const 这个关键字可以定义真正意义上的常量,也可以在某些情况下定义只读变量;

3,小实验:

1,下面的类定义是否合法?如果合法,ci 的值是什么,存储在哪里?

 1 #include <stdio.h>
2
3 class Test
4 {
5 private:
6 const int ci; // const 作用于 C++ 中的成员变量后得到的是只读成员变量,只读成员变量是不可以出现在成员符号左边的;所以会出现第 10 行的错误信息;
7 public:
8 /*
9 Test() // 在这里编译器显示:ci 是一个 const 成员,没有进行初始化;因此如果要初始化 ci 成员变量,必须要在这一行进行,这个时候就让初始化列表出厂了;
10 {
11 ci = 10; // 在这里编译器显示:ci 在这个类中是一个只读的成员变量;
12 }
13 */
14
15 /* 由上面的语句改换如下 */
16 Test() : ci(10) // ci 在初始化之后可以改变,因为 ci 在这里只是一个只读的成员变量,仅仅是不能出现在赋值符号左边而已;我们依旧可以通过指针的方式来修改 ci 里面的值;
17 {
18 // ci = 10;
19 }
20
21 int getCI()
22 {
23 return ci;
24 }
25 };
26
27 int main()
28 {
29 Test t; // 当这里没有手工定义上面程序中的无参构造函数的时候,显示有“未初始化的 const 的成员”的错误; 同时的当这里没有通过类来定义对象的时候,可以通过编译,说明 const 可以修饰 C++ 中的成员变量;
30
31 printf("t.ci = %d\n", t.getCI());
32
33 return 0;
34 }

4,C++ 中提供了初始化列表对成员变量进行初始化,其语法规则为:

1,代码示例:

1 ClassName::ClassName() : m1(v1), m2(v1, v2), m3(v3)  // 用 v1, (v1, v2), v3 分别对 m1, m2, m3 初始化;
2 {
3 // some other initialize operation;
4 }

1,初始化列表应该在构造函数的地方使用;

2,构造函数参数列表之后函数体之前定义初始化列表;

3,其作用就是对成员变量进行初始化;

2,注意事项(避免 bug 很重要):

1,成员的初始化顺序与成员的声明顺序相同;

2,成员的初始化顺序与初始化列表中的位置无关;

3,初始化列表先于构造函数的函数体执行;

(1)当构造函数的函数体开始执行的时候,对象已经创建完毕了,执行构造函数的函数体仅仅是为了初始化我们这个对象的状态而已;

(2)所以说初始化列表既然是用于初始化,那么必须在我们这个类对象创建的同时来进行执行,而不应该是对象已经创建好了才来进行一系列的初始化工作,这一点是有明确差异的,这个差异也就是初始化和赋值之间的差异;

5,初始化列表的使用编程实验:

 1 #include <stdio.h>
2
3 class Value
4 {
5 private:
6 // int mi = 0; // 要初始化成员变量,只能使用初始化列表;在构造函 数当中的那是对成员变量赋值,不是初始化;
7
8 int mi;
9
10 public:
11 Value(int i)
12 {
13 printf("i = %d\n", i);
14 mi = i;
15 }
16
17 int getI()
18 {
19 return mi;
20 }
21 };
22
23 class Test
24 {
25 private:
26 /*
27 Value m2(2); // 这种明确的调用一个参数的方式也是有语法错误的;
28 Value m3(3);
29 Value m1(1);
30 */
31 Value m2;
32 Value m3;
33 Value m1;
34
35 public:
36 /*
37 Test() // 这里编译器显示没有 value 类的无参构造函数来匹配调用;
38 {
39
40 }
41 */
42 Test() : m1(1), m2(2), m3(3) // 成员变量的初始化必须通过初始化列表来完成;
43 {
44 printf("Test::Test()\n"); // 初始化列表先于构造函数的函数体执行;
45 }
46 };
47
48 int main()
49 {
50 Test t;
51
52 return 0;
53 }

6,类中的 const 成员:

1,类中的 const 成员会被分配空间的;在这里注意:(只有编译时 用立即数初始化的才是真的常量,const成员在编译时 没法直接赋值,能不能进符号表 就看编译时是否可以直接知道值,类只是一个模子  所以不可能给模子赋值  只有在创建对象时才可能  因为创建对象时是分配空间的时候)

(1)const 成员分配的空间和我们整个类对象分配的空间一致;

2,类中的 const 成员的本质是只读变量;

(1)根据编译提供的错误 bug 信息而得来;

3,类中的const 成员只能在初始化列表中指定初始值;

(1)编译器无法直接得到 const 成员的初始值,因此无法进入符号表成为真正意义上的常量;

(2)  运行时才来定义对象申请空间,调用构造函数,继而来调用初始化列表初始化成员变量;

7,只读成员变量编程实验:

  1,代码示例:

 1 #include <stdio.h>
2
3 class Value
4 {
5 private:
6 int mi;
7 public:
8 Value(int i)
9 {
10 printf("i = %d\n", i);
11 mi = i;
12 }
13 int getI()
14 {
15 return mi;
16 }
17 };
18
19 class Test
20 {
21 private:
22 const int ci;
23
24 Value m2;
25 Value m3;
26 Value m1;
27
28 public:
29 Test() : m1(1), m2(2), m3(3), ci(100)
30 {
31 printf("Test::Test()\n");
32 }
33
34 int getCI()
35 {
36 return ci;
37 }
38
39 int setCI(int v)
40 {
41 int* p = const_cast<int*>(&ci); // 通过指针来操作常量对象;
42
43 *p = v;
44 }
45 };
46
47
48 int main()
49 {
50 Test t;
51
52 printf("t.ci = %d\n", t.getCI());
53
54 t.setCI(10);
55
56 printf("t.ci = %d\n", t.getCI());
57
58 return 0;
59 }

这个实验说明:类中的 const 成员不是真正意义上的常量,它只是只读变量(编译器告诉的);

8。小插曲:

1,初始化与赋值不同:

1,初始化:对正在创建的对象进行初始值设置;初始化的时候,对象还没创建好,在创建的同时,我们将它的值确定了;

2,赋值:对已经存在的对象进行值设置;

1 int main()
2 {
3 int i = 0; // 这是初始化,初始化的时候 i 还不存在;
4 // ...
5 i = 0; // 这是赋值, i 是实际存在的了,并且 i 已经有一个值了,这个时候将 i 的值被改变了
6 }

9,小结:

1,类中可以使用初始化列表对成员进行初始化;

(1)类中不能直接初始化成员变量(不论变量为一般的还是类的对象),只能通过初始化列表来初始化;

2,初始化列表先于构造函数体执行;

3,类中可以定义 const 成员变量(这里是变量);

(1)const 作用于类的成员后得到的仅是只读变量;

4,const 成员变量必须在初始化列表中指定初始值;

5,const 成员变量为只读变量;

C++中初始化列表的使用(总结)的更多相关文章

  1. c++中初始化列表的初始化变量顺序问题

    例题来看:请问下面程序打印出的结果是什么? #include <iostream> #include <string> using namespace std; class b ...

  2. C++中初始化列表的使用

    1,初始化列表是在 C++ 中才引入的: 2,以“类中是否可以定义 const 成员?”这个问题来引入初始化列表: 1,const 这个关键字可以定义真正意义上的常量,也可以在某些情况下定义只读变量: ...

  3. C++类的成员初始化列表的相关问题

    在以下四中情况下,要想让程序顺利编译,必须使用成员初始化列表(member initialization list): 1,初始化一个引用成员(reference member): 2,初始化一个常量 ...

  4. C++中使用初始化列表的情况

    http://blog.csdn.net/iceshirley/article/details/5688696 要理解这个问题,从概念上,我们要知道一点,那就是构造函数的执行过程会分成两个阶段:隐式或 ...

  5. 【c++】必须在类初始化列表中初始化的几种情况

    转自:http://www.cnblogs.com/kaituorensheng/p/3477630.html 1. 类成员为const类型 2. 类成员为引用类型 #include <iost ...

  6. C++-什么时候需要在类的构造函数中使用初始化列表

    1,如果基类没有default构造函数,则意味着其不能自己初始化.如果其被派生,派生类的构造函数要负责调用基类的构造函数,并传递给它需要的参数.下例中Base 2,如果类成员没有默认构造函数.下例中E ...

  7. Effective C++学习笔记:初始化列表中成员列出的顺序和它们在类中声明的顺序相同

    类成员的默认初始化顺序是按照声明顺序进行, 如果使用初始化列表初始化成员变量, 则必须按照成员变量的声明顺序进行; 否则, 在变量之间交替赋值时, 会产生, 未初始化的变量去赋值其他变量; 同时GCC ...

  8. C++中的初始化列表中可以对那些变量或对象进行初始化

    构造函数与其函数体之间可以添加初始化列表,能对某些对象进行初始化.格式为 类名() : 变量1(参数1),变量2(参数2) { } 1.     父类的对象的构造必须在初始化列表中,如: 子类名(): ...

  9. C++中为什么构造函数初始化列表

    已经有个构造函数负责初始化,为什么还需要构造函数初始化表呢? 在以下三种情况下需要使用初始化成员列表:一,需要初始化的数据成员是对象的情况:二,需要初始化const修饰的类成员:三,需要初始化引用成员 ...

随机推荐

  1. mysql集群--基于centos7

    1 MySQL主从备份 主机:192.168.43.8 从机:192.168.43.6 条件:主机和从机都安装了mysql,开启了二进制日志 安装mysql (mysql 和 mysql-server ...

  2. Docker入坑系列(二)

    Docker入坑系列(二) 上一篇我们为Docker创造了一个良好的生活环境,这一篇我们就开始让Docker活起来. 安装Docker ok,原文地址在这里. 当然,我只是自己翻译了一下而已- -跟着 ...

  3. js 把x,y轴两个数组变成[[x,y],[x,y]]的二维数组

    例如有X轴数组xarr=[2006,2007,2008],Y轴数组yarr=[12,15,18],代码如下: //调用 mergexy([2006,2007,2008],[12,15,18]); // ...

  4. 假如让你来设计SSL/TLS协议,你要怎么设计呢?

    摘要:本文将从设计者的视角介绍如何一步步设计出一个简易版的 SSL/TLS 的过程,在文章的最后,再简单介绍 TLS 1.2 版本的工作机制,以此帮助大家对 SSL/TLS 协议的基本原理有一个更深入 ...

  5. 07-Spring整合Mybatis

    Spring之整合Mybatis 整合核心思路 由很多框架都需要和Spring进行整合,而整合的核心思想就是把其他框架所产生的对象放到Spring容器中,让其成为Bean. 比如Mybatis,Myb ...

  6. 自学java一路以来,心血心得整理分享

    ✿ 贴心提示:文章内容比较长,但都是干货,请大家耐心看完.时间不够充裕的小伙伴,建议收藏,一定要耐心看完,保证对你有后续学习java有所帮助. 一.推荐背景介绍 (一)我是怎么学的? ★ 非常普通的人 ...

  7. Android 12(S) 图形显示系统 - 初识ANativeWindow/Surface/SurfaceControl(七)

    题外话 "行百里者半九十",是说步行一百里路,走过九十里,只能算是走了一半.因为步行越接近目的地,走起来越困难.借指凡事到了接近成功,往往是最吃力.最艰难的时段.劝人做事贵在坚持, ...

  8. 基于AE的基础的GIS系统的开发

    一个GIS系统需要的基本功能的代码 一些基本的拖拽操作就不讲了,直接上代码吧.   1. 打开.mxd文件 基本思路:判断mxd路径存在→打开mxd文件 string filename = Appli ...

  9. Python 实现 JWT 生成

    Python 实现 JWT 生成 JWT 简介:https://www.jianshu.com/p/576dbf44b2ae Json web token (JWT), 是为了在网络应用环境间传递声明 ...

  10. notepad++给每一列数据加单引号及逗号结尾

    原始数据: 对列操作--先加前引号(光标放在第一行哦):编辑-->列块编辑 再加后引号和逗号(文本尾端不齐,就用替换): 打开替换窗口:ctrl+F(其实就是查找) 加完引号和逗号效果:(如果最 ...