第20课 初始化列表的使用
1. 类成员的初始化
(1)C++中提供了初始化列表,可以对类的成员变量进行初始化
(2)语法规则:
ClassName::ClassName():m1(v1), m2(v2,v3),m3(v3) { //其它初始化操作 }
(3)注意事项
①成员的初始化顺序与成员的声明顺序相同。而与初始化列表中的位置无关
②初始化列表先于构造函数的函数体执行
【编程实验】初始化列表的使用 20-2.cpp
#include <stdio.h> class Value { private: int mi; public: Value(int i) { printf("i = %d\n", i); mi = i; } int getI(){return mi;} }; class Test { private: Value m2; Value m3; Value m1; public: //初始化顺序只与声明顺序有关,与初始化列表次序无关 //即初始化顺序为:m2,m3,m1。最后才是调用构造函数 Test():m1(1), m2(2), m3(3) //类的成员变量的初始化 { printf("Test::Test()\n"); } }; int main() { Test t; return 0; }
运行结果:
2. 类中的const成员变量
(1)类中的const成员会被分配空间。但本质上是个只读变量,因为编译器无法直接得到const成员的初始值,因此无法进入符号表成为真正意义上的常量。
【编程实验】类中的const成员(值为多少,存储在哪里?) 20-1.cpp
#include <stdio.h> class Test { private: //const成员,会分配空间。其存储空间与对象存储位置一样 //可在栈上、堆或全局区等 //但编译期间无法确定初始化,所以不会进入符号表 const int ci; public: Test() { //ci = 10; //不能这样初始化,ci是只读变量,不能作为左值 } int getCI(){return ci;} } int main() { Test t; //会提示ci变量未被初始化 printf("t.ci = %d\n", t.getCI()); return 0; }
运行结果:
(2)类中的const成员只能在初始化列表中指定初始值。而不能在其他地方(如构造函数的内部,因为形如 c = 1的赋值语句,意味着要给const变量赋值这是不允许的)。
【编程实验】只读成员变量 20-3.cpp
#include <stdio.h> class Value { private: int mi; public: Value(int i) { printf("i = %d\n", i); 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"); } int getCI(){return ci;} int setCI(int v) { //说明ci是个只读变量,可以通过指针修改内存值 int* p = const_cast<int*>(&ci); *p = v; } }; int main() { Test t; printf("t.ci = %d\n", t.getCI()); //100 t.setCI(10); printf("t.ci = %d\n", t.getCI()); //10 return 0; }
(3)小插曲:初始化与赋值不同
①初始化:对正在创建的对象进行初值设置(如int a = 1;或初始化列表的形式)
②赋值:对己经存在的对象进行值设置 (如 a = 1;)
3. 小结
(1)类中可以使用初始化列表对成员变量进行初始化
(2)初始化列表先于构造函数体执行
(3)类中可以定义const成员变量
(4)const成员变量必须在初始化列表中指定初值
(5)const成员变量为只读变量