class Date { public: Date(int year = 1, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } private: int _year; int _month; int _day; };
构造函数体内的语句只能称为赋初值,不能称为初始化。初始化只能初始化一次,而构造函数体内可以多次赋值。
一、初始化列表
1.1 定义
初始化列表:以一个:
开始,用,
分隔的数据成员列表,每个“成员变量”后跟一个()
,其中放初始值或表达式。
// Date类
Date(int year = 1, int month = 1, int day = 1)
:_year(year)
,_month(month)
,_day(day)
{}
// Stack类
class Stack()
{
public:
Stack(int capacity = 3)
:_a((int*)malloc(sizeof(int) * capacity))
,_top(0)
,_capacity(capacity)
{
if (nullptr == _a)
{
perror("malloc");
}
}
private:
int* _a;
int _top;
int _capacity;
}
PS:
-
每个成员变量只能在初始化列表出现一次。(只能初始化一次)
-
类中包含
引用成员变量
、const成员变量
、自定义类型成员(且该类没有默认构造函数时)
,必须在初始化列表进行初始化。
class A
{
public:
A(int a)
:_a(a)
{}
private:
int _a;
};
class B
{
public:
B(int d = 1)
:_a1(1)// 没有默认构造函数
,_b(d)// 引用成员变量
,_b2(2)// const成员
{}
private:
A _a1;
int& _b;
const int _b2;
};
除此以外,初始化列表和函数体可以混用,如上Stack类
中情形。
- 成员变量在类中的声明次序,就是成员变量在初始化列表中初始化顺序,与其在初始化列表中出现先后无关。
观察以下情形:
class A { public: A(int a) :_a1(a) ,_a2(_a1) {} private: int _a2; int _a1; }; int main() { A a(1); return 0; }