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; }