作用:初始化列表用于初始化类的成员变量。
语法:再构造函数体之后,函数体之前进行初始化,是初始化列表,用v1对m1进行初始化,用v1和v2对m2进行初始化
ClassName ::ClassName():m1(v1), m2(v1,v2), m3(v3)
{
// do something
}
#include <stdio.h> class Test { private: const int ci; // 初始化列表 public: Test() ci(10); { } int getCI() { return ci; } };
注意:
1. 成员变量的初始化只能通过初始化列表。
1. 成员初始化顺序和成员声明顺序相同。
2. 成员初始化列表优先于构造函数体执行。
3. 成员的初始化顺序不依赖于成员在初始化列表中的位置。(m1, m2, m3的初始化顺序并不是从左到右依次执行,决定于成员的声明顺序)
类中的const成员变量:
1. 类中的const成员会被分配空间,且分配的空间和类被分配的空间是一致的。
2. 类中的const只能在初始化列表中被初始化。
3. 编译器无法得到const成员的初始值,所以无非是进入符号表变成常量。
#include <stdio.h> class Value { private: int mi; public: Value(int i) { printf("i = %d\n", i); //成员的声明顺序,所以打印的顺序为 100,2,3,1 mi = i; } int getI() { return mi; } }; class Test { private: const int ci; // 成员的声明顺序 Value m2; Value m3; Value m1; public: Test() : m1(1), m2(2), m3(3), ci(100) // 成员的初始化列表 { printf("Test::Test()\n"); // 构造函数的函数体在初始化列表后执行,所以打印的顺序为 100,2,3,1,"Test::Test()" } int getCI() { return ci; } int setCI(int v) { int* p = const_cast<int*>(&ci); // 通过强制类型转换将只读属性去掉 *p = v; } }; int main() { Test t; printf("t.ci = %d\n", t.getCI()); t.setCI(10); printf("t.ci = %d\n", t.getCI()); return 0; }
栈里的对象构造顺序: 取决于程序执行流。
堆里的对象构造顺序: 依赖于new关键字的使用顺序。
全局的对象构造顺序: 全局的对象构造顺序不确定,取决于编译器。
#include <stdio.h> class Test { public: Test(const char* s) { printf("%s\n", s); } };
#include "test.h" Test t1("t1"); Test t2("t2"); Test t3("t3"); Test t4("t4"); // 全局对象构造时间在main()函数之前,但是这四个构造的顺序不确定 int main() { Test t5("t5"); }
原文:https://www.cnblogs.com/zsy12138/p/10713031.html