💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃个人主页 :阿然成长日记 👈点击可跳转
📆 个人专栏: 🔹数据结构与算法🔹C语言进阶🔹C++
🚩 不能则学,不知则问,耻于问人,决无长进
🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍
文章目录
- 一、问题引入
- 二、初始化的概念
- 三、什么是初始化列表
- 四、 初始化列表的格式
- 五、初始化列表的使用
- 1._a和_b已经有了缺省值,但是没有在初始化列表中显示写出。
- 2.同时在初始化列表又有缺省值
- 六、注意事项
一、问题引入
如下代码
class A {
//成员函数
private:int _a; int _b;//const修饰的变量const int _t
};
会出现如下结果
那这是为什么呢?
- 我们知道,对于下面这个类A的成员变量_a和_b属于
声明
,还没有在内存中为其开辟出一块空间以供存放,真正开出空间则是在定义
的时候,那何时定义呢?也就是使用这个类A去实例化出对象的时候。 - 但是,对于_t变量来说,他是一个const成员变量,学过的都知道const修饰的变量必须为其赋初始值。编译后报出了错误说【必须初始化常量对象】,因为对于const修饰的变量在声明的时候是必须要去进行初始化的,也就是要给到一个值
- 之前有讲过,若是我们自己不去实现构造函数的话,类中会默认提供一个构造函数来初始化成员变量,对于【内置类型】的变量不会处理,对【自定义类型】的变量会去调用它的构造函数。那么对于这里的_a1、_a2、_x都属于内置类型的数据,所以编译器不会理睬,可是呢const修饰的变量又必须要初始化,这个时候该怎么办呢
为了解决这个问题,祖师爷就提出了初始化列表
。
解决方法一: 给缺省值
使用C++11里面为内置类型不初始化打了一个补丁,在声明的位置给到一个初始化值,就可以很好地防止编译器不处理的问题。
const int _t = 1;
方法二: 使用初始化列表
接下来就开始初始化列表的学习!
二、初始化的概念
- 在了解【初始化列表】前,首先知道初始化的真正含义是什么
概念:在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。
class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};
- 虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化,构造函数体中的语句只能将其称为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值
三、什么是初始化列表
以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式
四、 初始化列表的格式
就拿之前写过的日期类为例
class Date
{
public:Date(int year, int month, int day):_year(year), _month(month), _day(day){}
private:int _year;int _month;int _day;
};
int main(void)
{Date d(2023, 3, 30);return 0;
}
五、初始化列表的使用
1._a和_b已经有了缺省值,但是没有在初始化列表中显示写出。
class A {//成员函数
public :A():_t(888){}
private:int _a = 666;int _b = 999;//const修饰的变量const int _t;
};
int main()
{A a;return 0;
}
由上图可以得出
- 1.哪个对象调用构造函数,初始化列表是它所有成员变量定义的位置
- 2.不管是否显式在初始化列表写,编译器都会为每个变量在初始化列表进行初始化
2.同时在初始化列表又有缺省值
class A {//成员函数
public :A():_a(444),_t(888){}
private:int _a = 666;int _b = 999;//const修饰的变量const int _t;
};
int main()
{A a;return 0;
}
结果如下图
结论:
- 这里要明确的一个概念是,缺省参数只是一个备份,若是我们没有去给到值初始化的话,编译器就会使用这个初始值,若是我们自己给到了明确的值的话,不会去使用这个缺省值了
六、注意事项
1. 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)
2. 类中包含以下成员,必须放在初始化列表位置进行初始化
(1) 🔸引用成员变量
通过编译可以看出,这个引用型成员变量_z需要被初始化,它必须要引用一个值
(2)🔸 const成员变量
这个在前面已经说到过了,const修饰的成员变量和构造函数对于内置类型不做处理产生了一个冲突,因此祖师爷就提出了【初始化列表】这个概念
(3)🔸 自定义类型成员
写了有参构造编译器就不会提供默认构造。也就是说当存在自定义类型的时候,我们还是尽量使用初始化列表,
3.尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。
4. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关
- 所以建议我们在写初始化列表时,尽量顺序与成员变量定义一致。