前言
- 🚄 输入是学习的本质,输出是学习的手段。
- 🔖 分享每一次的学习,期待你我都有收获。
- 🎇 欢迎🔎关注👍点赞⭐️收藏✉评论,共同进步!
- 🌊 “要足够优秀,才能接住上天给的惊喜和机会”
- 💬 博主水平有限,如若有误,请多指正,万分感谢!
初始化列表
用法:
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。
探讨初始化列表,就能明白成员变量是什么时候被创造出来的。
初始化列表用于构造函数,可以用来对成员变量进行初始化
我们先创建一个日期类:
class Date
{
public:
void Print() //打印
{
cout << _year << " - " << _month << " - " << _day << endl;
}
Date(int year = 0, int month = 1, int day = 1,int capacity = 4)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
return 0;
}
现阶段,我们最熟悉的初始化方法是这样的:
Date(int year = 0, int month = 1, int day = 1,int capacity = 4)
{
_year = year;
_month = month;
_day = day;
}
运用初始化列表我们可以这样写:
Date(int year = 0, int month = 1, int day = 1):_year(year),_month(month),_day(day)
{
;
}
那有些同学就要有疑问了,这不是吃饱了没事找事吗?
这样写既麻烦也没有第一种简洁明了为什么还要用
不急,我们再来看这样一组代码对比:
注意:这里我又给 _year 赋值了一遍,所以编译器给我报错了
但是如果我是用第一种方法:
编译器完全不报错,这里已经暗示这两种方法其实是有区别的。
如果我们在成员变量中加点不一样的成员,初始化列表的作用就能体现出来了。
class Date
{
public:
void Print() //打印
{
cout << _year << " - " << _month << " - " << _day << endl;
}
Date(int year = 0, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
_n = 10;
}
private:
int _year;
int _month;
int _day;
const int _n; //加个const修饰的成员
};
int main()
{
return 0;
}
这里的意思就是,_n必须用初始化列表初始化。
我们再看一个例子,一会儿一起解释。
int _year;
int _month;
int _day;
const int _n; //加个const修饰的成员
int& ret; //再加个引用类型
我们说引用类型必须初始化,可是类只是一个类似模板一样的东西,在类里无法初始化(缺省值≠初始化)。
那ret怎么初始化?是否无法完成初始化?
Date(int year = 0, int month = 1, int day = 1,int& b)
{
_year = year;
_month = month;
_day = day;
_n = 10;
ret = b;
}
如果我们使用的是初始化列表,程序就不会报任何错误
Date(int& b,int year = 0, int month = 1, int day = 1)
:_year(year),
_month(month),
_day(day),
_n(10),
ret(b)
{
;
}
到此我们就可以理解了:
类只是对成员变量、成员函数的声明,声明和定义有时是分开的,就像是
int x; //初始化为随机值
x=10; //这里已经不是初始化了,而是赋值。
而初始化列表的作用,就是对类成员变量进行初始化。
无论是内置类型也好,自定义类型也好,显然,初始化只会进行一次
因此才会出现这样的错误
初始化两次是不可以的。
题外话:新版本的C++是支持这种写法的——在类里给成员变量赋值,但是这样的本质是给缺省值,
证据是,如果我们在实例化对象时传实参给构建函数,可以调用初始化列表初始化,
并且最后得到的日期依然是我们传的日期。
class Date
{
public:
Date(int year = 0, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
_n = 10;
}
private:
int _year = 10;
int _month = 1;
int _day = 1;
const int _n; //加个const修饰的成员
};
总结:在类中,对于一些特殊的成员变量——必须在声明的同时初始化,有两种解决方法:
- 初始化列表初始化
- 给缺省值初始化
注:成员变量初始化的顺序与其在初始化列表中出现的顺序无关,只由声明的先后顺序有关。
先声明,先初始化
样例:
下面程序的运行结果是( )?
class A
{
public:
A(int a) :_a1(a), _a2(_a1)
{
;
}
void Print()
{
cout << _a1 << " " << _a2 << endl;
}
private:
int _a2;
int _a1;
};
int main()
{
A aa(1);
aa.Print();
}
因为_a2先声明,所以先初始化 _ a2=_a1,此时的 _a1因为还没初始化,所以 _a2是随机值
然后才是 _a1= a