目录
成员变量初始化的顺序就是成员变量在类中的声明次序,与初始化列表中的先后次序无关
基本概念
自定义一个类如下:
成员属性为x, y, z
class Thing{
public:
private:
int x;
int y;
int z;
};
初始化列表的意义:
对类的成员变量进行初始化;
使用初始化列表原因:
格式:
与其他函数不同,构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表,初始化列表以冒号开头,后跟一系列以逗号分隔的初始化字段
class foo
{
public:
foo(string s, int i):name(s), id(i){} ; // 初始化列表
private:
string name ;int id ;
};
使用注意:
- 每个成员变量在初始化列表中只能出现一次(初始化列表能只能初始化一次,多次初始化会报错);
- 类中包含以下成员,必须放在初始化列表位置进行初始化:
引用成员变量
const成员变量
没有默认构造函数的自定义类型成员 - 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。
- 成员变量初始化的顺序就是成员变量在类中的声明次序,与初始化列表中的先后次序无关
举例说明
const成员只能用初始化列表方式
- 在构造函数中使用赋值语句初始化成员变量:
程序运行结果:
- 将成员属性x变为常量:const int x;此时使用构造函数赋值语句方式初始化,程序将报错;原因:常量是不允许被赋值的,即上述错误等同于:const int x; a=5; 常量是不能先定义,再对其进行赋值的:错误代码如下:
程序运行报错:
- 针对上述类成员变量是常量的情况,只能使用初始化列表方式:
程序运行结果:
引用成员只能用初始化列表方式
- 错误示范:使用构造函数赋值语句初始化类的引用变量;程序将报错;原因分析:x=a表示x是a的别名?不是,实际意思是给引用变量x赋值为a,但是此时x是谁的引用是不知道的;更无法进行赋值;
这种错误等同于:给引用x赋值,但此时x是没有指向的;
- 正确方式:初始化列表方式为类的引用变量赋值;下列表示:x是a的引用;
- 建议:在编写程序时,能用初始化列表方式时,尽量用这种方式;
- 初始化列表方式,完整举例:
成员变量初始化的顺序就是成员变量在类中的声明次序,与初始化列表中的先后次序无关
如下代码,类成员变量中先声明了_a2,再声明了_a1,因此初始化的顺序是先初始化_a2,再初始化_a1:
#include <iostream>
using namespace std;
class A
{
public:
A(int a)
: _a1(a)
, _a2(_a1)
{}
void Print()
{
cout << _a1 << " " << _a2 << endl;
}
private:
int _a2;//先声明_a2
int _a1;//后声明_a1
};
int main() {
A aa(1);
aa.Print();
}
先声明_a2就会先初始化_a2,用_a1初始化_a2,由于此时_a1还是随机值,因此_a2的值也是随机值,_a1使用a的值1进行初始化,因此,_a1的值为1: