首页 > 代码库 > 第20课 - 初始化列表的使用

第20课 - 初始化列表的使用

第20课 - 初始化列表的使用

0. 问题

  类中是否可以定义 const 成员?

  下面的类定义是否合法?如果合法ci 的值是什么存储在哪里

1 class Test
2 {
3 private:
4     const int ci;
5 public:
6     int getCI() { return ci;}
7 };
技术分享
 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成员

在C中:const 修饰的变量必须在定义的时候进行初始化,不能在定义之后对其进行赋值操作,违背了const 的含义。

在C++中:构造函数内部是对成员变量进行赋值操作,而不是初始化。初始化需要初始化列表。

1. 类成员的初始化

  (1)C++ 中提供了初始化列表,可以对成员变量进行初始化

  (2)语法规则:

ClassName::ClassName():m1(v1), m2(v2,v3),m3(v3) 
{
     //其它初始化操作
}
技术分享
 1 // 构造函数是对变量进行赋值操作,初始化列表是进行初始化操作,两个是不同的概念
 2 
 3 #include <stdio.h>
 4 
 5 class Test
 6 {
 7 private:
 8     int i;
 9     int j;
10     const int k;
11 public:
12     int getI()
13     {
14         return i;
15     }
16     int getJ()
17     {
18         return j;
19     }
20     int getK()
21     {
22         return k;
23     }
24     
25     Test() : k(10)
26     {
27         printf("invoke consttuctor!\n");
28         i = 1;
29         j = 2;
30     }
31 };
32 
33 int main(void)
34 {
35     Test t1;
36     
37     printf("t1.getI() = %d, t1.getJ() = %d, t1.getK() = %d\n", t1.getI(), t1.getJ(), t1.getK());
38 
39     return 0;
40 }
const变量的初始化(解决构造函数中不能初始化)

  (3)注意事项

    ① 成员的初始化顺序与成员的声明顺序相同,而与初始化列表中的位置无关

    ② 初始化列表先于构造函数的函数体执行

技术分享
 1 #include <stdio.h>
 2 
 3 class value
 4 {
 5 private:
 6     int m_i;
 7 public:
 8     value(int val) : m_i(100)
 9     {
10         printf("in value!\n");
11         printf("m_i = %d\n", m_i);
12         m_i = val;
13     }    
14 
15     int getM_i()
16     {
17         return m_i;
18     }
19 };
20 
21 class Test
22 {
23 private:
24     value m1;
25     value m2;
26 public:
27     Test() : m1(1), m2(2)    // 初始化列表,对m1, m2进行初始化。初始化还是调用value类中的构造函数,但还是先执行value中的初始化列表
28     {
29         printf("in Test!\n");
30     }
31     
32     int get()
33     {
34         return m1.getM_i();
35     }
36 };
37 
38 int main(void)
39 {
40     Test t1;
41     
42     printf("t1.get() = %d\n", t1.get());
43     
44     return 0;
45 }
初始化列表的使用

2. 类中的 const 成员

  (1)类中的 const 成员会被分配空间,局部对象会分配栈空间、动态对象会分配堆空间、全局对象会分配静态存储空间(和const int i; 不同)

  (2)类中的 const 成员的本质是只读变量,可以通过指针隐式的修改。编译器无法直接得到 const 成员的初始值,因此无法进入符号表成为真正意义上的常量

  (3)类中的 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 
14     int getI()
15     {
16         return mi;
17     }
18 };
19 
20 class Test
21 {
22 private:
23     const int ci;
24     Value m2;
25     Value m3;
26     Value m1;
27 public:
28     Test() : m1(1), m2(2), m3(3), ci(100)  // 成员变量的初始化
29     {
30         printf("Test::Test()\n");
31     }
32     
33     int getCI()
34     {
35         return ci;
36     }
37 
38     int setCI(int v)
39     {
40         // 说明ci是个只读变量,可以通过指针修改内存值
41         int* p = const_cast<int*>(&ci);
42         *p = v;
43     }
44 };
45 
46 int main()
47 {
48     Test t;
49 
50     printf("t.ci = %d\n", t.getCI());
51 
52     t.setCI(10);
53 
54     printf("t.ci = %d\n", t.getCI());
55 
56     return 0;
57 }
const只读成员变量

小插曲初始化赋值不同

  (1)初始化:对正在创建的对象进行初值设置
  (2)赋值:   对已经存在的对象进行值设置

3. 小结

  (1)类中可以使用初始化列表对成员进行初始化

  (2)初始化列表先于构造函数体执行

  (3)类中可以定义 const 成员变量

  (4)const 成员变量必须在初始化列表中指定初始值

  (5)const 成员变量为只读变量

 

第20课 - 初始化列表的使用