构造函数体赋值
在创建对象时,编译器通过调用构造函数, 给对象中各个成员变量一个合适的初值
比如之前的Date类:
class Date
{
int m_year;
int m_month;
int m_day;
public:
Date(int year, int month, int day)
{
m_year = year;
m_month = month;
m_day = day;
}
};
这样的话, 虽然上述构造函数调用之后, 对象当中已经有了一个初始值, 但是并不能将其称作为类对象成员的初始化, 构造函数体当中的语句只能将其称作赋初值, 而不能称作初始化, 因为初始化只能够初始化一次, 而构造函数体内可以多次赋值.
初始化列表
初始化列表: 以一个冒号开始, 接着使用逗号分隔每一个数据成员, 每个"成员变量"后面跟一个放在括号中的初始值或表达式
比如下面这样:
class Date
{
int m_year;
int m_month;
int m_day;
public:
Date(int year, int month, int day) :
m_year(year),
m_month(month),
m_day(day)
{
}
};
注意
- 每个成员变量在初始化列表中只能够出现一次(初始化只能够初始化一次)
- 类中包含以下成员, 必须放在初始化列表位置进行初始化
引用成员变量
const成员变量
没有默认构造函数的类的对象
代码示例:
class A
{
int m_a;
public:
A(int a) :
m_a(a)
{
}
};
class B
{
A aa;
int & ret;
const int m_n;
public:
B(int a, int num) :
aa(a),
ret(num),
m_n(10)
{
}
};
尽量使用初始化列表进行初始化, 因为不管我们是否使用初始化列表, 对于自定义类型成员变量, 一定会先使用初始化列表初始化
成员变量在类中声明次序就是其在初始化列表中的初始化顺序, 与其在初始化列表中的先后次序无关.
explicit关键字
#include <iostream>
using namespace std;
class Date
{
int m_year;
public:
Date(int year) :
m_year(year)
{
}
};
int main()
{
Date a = 2019;
system("pause");
return 0;
}
单参构造函数可以用 = 直接调用
而 explicit 关键字就是阻止单参构造的不规范调用
#include <iostream>
using namespace std;
class Date
{
int m_year;
public:
explicit Date(int year) :
m_year(year)
{
}
};
int main()
{
Date a = 2019;
system("pause");
return 0;
}
给构造函数加上 explicit 关键字之后, 就会编译出错