C++中初始化列表的使用
1,初始化列表是在 C++ 中才引入的;
2,以“类中是否可以定义 const 成员?”这个问题来引入初始化列表:
1,const 这个关键字可以定义真正意义上的常量,也可以在某些情况下定义只读变量;
3,小实验:
1,下面的类定义是否合法?如果合法,ci 的值是什么,存储在哪里?
#include <stdio.h> class Test
{
private:
const int ci; // const 作用于 C++ 中的成员变量后得到的是只读成员变量,只读成员变量是不可以出现在成员符号左边的;所以会出现第 10 行的错误信息;
public:
/*
Test() // 在这里编译器显示:ci 是一个 const 成员,没有进行初始化;因此如果要初始化 ci 成员变量,必须要在这一行进行,这个时候就让初始化列表出厂了;
{
ci = 10; // 在这里编译器显示:ci 在这个类中是一个只读的成员变量;
}
*/ /* 由上面的语句改换如下 */
Test() : ci() // ci 在初始化之后可以改变,因为 ci 在这里只是一个只读的成员变量,仅仅是不能出现在赋值符号左边而已;我们依旧可以通过指针的方式来修改 ci 里面的值;
{
// ci = 10;
} int getCI()
{
return ci;
}
}; int main()
{
Test t; // 当这里没有手工定义上面程序中的无参构造函数的时候,显示有“未初始化的 const 的成员”的错误; 同时的当这里没有通过类来定义对象的时候,可以通过编译,说明 const 可以修饰 C++ 中的成员变量; printf("t.ci = %d\n", t.getCI()); return ;
}
4,C++ 中提供了初始化列表对成员变量进行初始化,其语法规则为:
1,代码示例:
ClassName::ClassName() : m1(v1), m2(v1, v2), m3(v3) // 用 v1, (v1, v2), v3 分别对 m1, m2, m3 初始化;
{
// some other initialize operation;
}
1,初始化列表应该在构造函数的地方使用;
2,构造函数参数列表之后函数体之前定义初始化列表;
3,其作用就是对成员变量进行初始化;
2,注意事项(避免 bug 很重要):
1,成员的初始化顺序与成员的声明顺序相同;
2,成员的初始化顺序与初始化列表中的位置无关;
3,初始化列表先于构造函数的函数体执行;
1,当构造函数的函数体开始执行的时候,对象已经创建完毕了,执行构造函数的函数体仅仅是为了初始化我们这个对象的状态而已;
2,所以说初始化列表既然是用于初始化,那么必须在我们这个类对象创建的同时来进行执行,而不应该是对象已经创建好了才来进行一系列的初始化工作,这一点是有明确差异的,这个差异也就是初始化和赋值之间的差异;
5,初始化列表的使用编程实验:
#include <stdio.h> class Value
{
private:
// int mi = 0; // 要初始化成员变量,只能使用初始化列表;在构造函 数当中的那是对成员变量赋值,不是初始化; int mi; public:
Value(int i)
{
printf("i = %d\n", i);
mi = i;
} int getI()
{
return mi;
}
}; class Test
{
private:
/*
Value m2(2); // 这种明确的调用一个参数的方式也是有语法错误的;
Value m3(3);
Value m1(1);
*/
Value m2;
Value m3;
Value m1; public:
/*
Test() // 这里编译器显示没有 value 类的无参构造函数来匹配调用;
{ }
*/
Test() : m1(), m2(), m3() // 成员变量的初始化必须通过初始化列表来完成;
{
printf("Test::Test()\n"); // 初始化列表先于构造函数的函数体执行;
}
}; int main()
{
Test t; return ;
}
6,类中的 const 成员:
1,类中的 const 成员会被分配空间的;
1,const 成员分配的空间和我们整个类对象分配的空间一致;
2,类中的 const 成员的本质是只读变量;
1,根据编译提供的错误 bug 信息而得来;
3,类中的 oonst 成员只能在初始化列表中指定初始值;
1,编译器无法直接得到 const 成员的初始值,因此无法进入符号表成为真正意义上的常量;
1,因为只能在运行时才来定义对象,调用构造函数,继而来调用初始化列表初始化成员变量;
7,只读成员变量编程实验:
1,代码示例:
#include <stdio.h> class Value
{
private:
int mi;
public:
Value(int i)
{
printf("i = %d\n", i);
mi = i;
}
int getI()
{
return mi;
}
}; class Test
{
private:
const int ci; Value m2;
Value m3;
Value m1; public:
Test() : m1(), m2(), m3(), ci()
{
printf("Test::Test()\n");
} int getCI()
{
return ci;
} int setCI(int v)
{
int* p = const_cast<int*>(&ci); // 通过指针来操作常量对象; *p = v;
}
}; int main()
{
Test t; printf("t.ci = %d\n", t.getCI()); t.setCI(); printf("t.ci = %d\n", t.getCI()); return ;
}
2,这个实验说明:
1,类中的 const 成员不是真正意义上的常量,它只是只读变量(编译器告诉的);
8,小插曲:
1,初始化与赋值不同:
1,初始化:对正在创建的对象进行初始值设置;
1,初始化的时候,对象还没创建好,在创建的同时,我们将它的值确定了;
2,赋值:对已经存在的对象进行值设置;
int main()
{
int i = ; // 这是初始化,初始化的时候 i 还不存在;
// ...
i = ; // 这是赋值, i 是实际存在的了,并且 i 已经有一个值了,这个时候将 i 的值被改变了
}
9,小结:
1,类中可以使用初始化列表对成员进行初始化;
1,类中不能直接初始化成员变量(不论变量为一般的还是类的对象),只能通过初始化列表来初始化;
2,初始化列表先于构造函数体执行;
3,类中可以定义 const 成员变量(这里是变量);
1,const 作用于类的成员后得到的仅是只读变量;
4,const 成员变量必须在初始化列表中指定初始值;
5,const 成员变量为只读变量;
C++中初始化列表的使用的更多相关文章
- c++中初始化列表的初始化变量顺序问题
例题来看:请问下面程序打印出的结果是什么? #include <iostream> #include <string> using namespace std; class b ...
- C++中初始化列表的使用(总结)
原文链接 https://www.cnblogs.com/dishengAndziyu/p/10906081.html 参考链接:https://www.cnblogs.com/laiqun/p/57 ...
- C++类的成员初始化列表的相关问题
在以下四中情况下,要想让程序顺利编译,必须使用成员初始化列表(member initialization list): 1,初始化一个引用成员(reference member): 2,初始化一个常量 ...
- C++中使用初始化列表的情况
http://blog.csdn.net/iceshirley/article/details/5688696 要理解这个问题,从概念上,我们要知道一点,那就是构造函数的执行过程会分成两个阶段:隐式或 ...
- 【c++】必须在类初始化列表中初始化的几种情况
转自:http://www.cnblogs.com/kaituorensheng/p/3477630.html 1. 类成员为const类型 2. 类成员为引用类型 #include <iost ...
- C++-什么时候需要在类的构造函数中使用初始化列表
1,如果基类没有default构造函数,则意味着其不能自己初始化.如果其被派生,派生类的构造函数要负责调用基类的构造函数,并传递给它需要的参数.下例中Base 2,如果类成员没有默认构造函数.下例中E ...
- Effective C++学习笔记:初始化列表中成员列出的顺序和它们在类中声明的顺序相同
类成员的默认初始化顺序是按照声明顺序进行, 如果使用初始化列表初始化成员变量, 则必须按照成员变量的声明顺序进行; 否则, 在变量之间交替赋值时, 会产生, 未初始化的变量去赋值其他变量; 同时GCC ...
- C++中的初始化列表中可以对那些变量或对象进行初始化
构造函数与其函数体之间可以添加初始化列表,能对某些对象进行初始化.格式为 类名() : 变量1(参数1),变量2(参数2) { } 1. 父类的对象的构造必须在初始化列表中,如: 子类名(): ...
- C++中为什么构造函数初始化列表
已经有个构造函数负责初始化,为什么还需要构造函数初始化表呢? 在以下三种情况下需要使用初始化成员列表:一,需要初始化的数据成员是对象的情况:二,需要初始化const修饰的类成员:三,需要初始化引用成员 ...
随机推荐
- java 接口概念及使用
package java11; /* 在任何版本的java中,接口都能定义抽象方法 格式: public abstrace 返回值类型 方法名称(参数列表): 注意事项: 1.接口当中的抽象方法,修饰 ...
- CSS9:动态 REM-手机专用的自适应方案
CSS9:动态 REM-手机专用的自适应方案 动态 REM是手机专用,是如何适配所有手机的方案,不是响应式方案,例如 : taobao.com 是专门的PC端m.taobao.com 是专门的手机端, ...
- shell编程之基础知识1
1.shell脚本的基本格式 #!bin/bash ->看到这个就是shell脚本 #filename:test.sh ->脚本名称 #auto echo hello world -& ...
- Java调用明华RF读写器DLL文件的方法
首先jdk必须得是32位的,IDE也必须是32位的(我用的idea,所以为了使用32位的,下载了2018年1月版本的). 明华RF读写器演示文件提供了一份名为mwrf32.dll的动态链接库文件 ja ...
- Halo(十一)
Spring Boot 继承 AbstractErrorController 实现全局异常处理 @RequestMapping("${server.error.path:${error.pa ...
- Idea的几个常用的
sout+tab= "System.out.println()" ctrl+alt+v=生成当前对象的实例 ctrl+shift+enter="(真个是真的牛哦)直接 ...
- Jmeter性能测试,使用ServerAgent监控服务端性能指标
一.jmeter1.下载JMeter Plugins Manager.jar放到你的jmeter\lib\ext目录下2.启动jmeter,进入Plugins Manager找到perfmon安装这个 ...
- phpstudy的80端口被占用问题
1.查看电脑中当前程序占用的端口和程序ID 当phpstudy设置端口号为80时显示占用,在命令行中输入:netstat -ano 就可以看到当前电脑中程序占用的端口和程序ID等等信息 2.查看正在运 ...
- window环境下pipd的安装
参照:https://blog.csdn.net/jin80506/article/details/83111848 如果你还是无法使用尝试查看是否自己已经将:C:\software\Python\P ...
- windows防火墙批量开放端口
windows自带的防火墙没有增加端口范围的功能,这让一些常见的配置变得非常麻烦(比如FTP被动模式下,就需要在防火墙上开启端口范围),经过查询资料,使用以下cmd批处理内容,即可增加端口范围: ec ...