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;
}
运行结果:
类中的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成员变量为只读变量