类中是否可以定义const成员?
小实验:
类中的const成员实验:
1 #include <stdio.h> 2 3 class Test 4 { 5 private: 6 const int ci; 7 public: 8 Test() 9 { 10 ci = 10; 11 } 12 int getCI() 13 { 14 return ci; 15 } 16 }; 17 18 19 int main() 20 { 21 Test t; 22 23 printf("t.ci = %d\n", t.getCI()); 24 25 return 0; 26 }
编译结果如下:
可以看到用这个类定义一个对象时,const成员必须要初始化。但是这个初始化不能在构造函数中去做。
因为ci是只读变量,只读变量是不能出现在赋值符号的左边的,所以第10行会报错。编译器提示我们要在第八行进行初始化,第八行怎么进行呢?
初始化列表:
类成员的初始化:
合法的初始化如下:
运行结果如下:
ci的值在初始化过后仍然可以改变,因为它只是一个只读变量,不能出现在赋值符号的左边,但是我们可以通过一个指针来改变。
初始化列表的注意事项:
初始化列表的初始化是在类对象的创建过程中进行的,而不是类对象创建好了之后才进行。
初始化列表的使用示例:
1 #include <stdio.h> 2 3 class Value 4 { 5 private: 6 int mi; 7 public: 8 Value(int i) 9 { 10 printf("i = %d\n", i); 11 mi = i; 12 } 13 int getI() 14 { 15 return mi; 16 } 17 }; 18 19 class Test 20 { 21 private: 22 Value m2; 23 Value m3; 24 Value m1; 25 public: 26 Test() : m1(1), m2(2), m3(3) 27 { 28 printf("Test::Test()\n"); 29 } 30 }; 31 32 33 int main() 34 { 35 Test t; 36 37 return 0; 38 }
类对象成员变量的初始化也必须通过初始化列表来完成。
运行结果如下:
可以看到初始化顺序是m2、m3、m1,和他们的定义顺序是一样的。而Test的构造函数是在初始化列表之后进行的。
类中的const成员:
类中const成员的所在的空间和它所在的对象所在的空间是一致的,对象在栈上,const成员就在栈上,对象在堆上,const成员就在堆上。
示例程序:
1 #include <stdio.h> 2 3 class Value 4 { 5 private: 6 int mi; 7 public: 8 Value(int i) 9 { 10 printf("i = %d\n", i); 11 mi = i; 12 } 13 int getI() 14 { 15 return mi; 16 } 17 }; 18 19 class Test 20 { 21 private: 22 const int ci; 23 Value m2; 24 Value m3; 25 Value m1; 26 public: 27 Test() : m1(1), m2(2), m3(3), ci(100) 28 { 29 printf("Test::Test()\n"); 30 } 31 int getCI() 32 { 33 return ci; 34 } 35 int setCI(int v) 36 { 37 int* p = const_cast<int*>(&ci); 38 39 *p = v; 40 } 41 }; 42 43 44 int main() 45 { 46 Test t; 47 48 printf("t.ci = %d\n", t.getCI()); 49 50 t.setCI(10); 51 52 printf("t.ci = %d\n", t.getCI()); 53 54 return 0; 55 }
运行结果如下:
可以看到const成员就是只读变量,编译器不会去符号表中取它的值,我们可以通过指针更改const成员的值。
小插曲:
在C语言中,int i=0是初始化, int i; i = 0这是赋值。它们是不一样的。
小结: