第20課 初始化列表的使用


初始化列表(上)

類中是否可以定義const成員?
下面的類定義是否合法?
如果合法,ci的值是什么,存儲在哪里?
class Test
{
private:
  const int ci;
public:
  int getCI() { return ci; }
}

編程實驗:類中是否可以存在const成員?

 1 #include <stdio.h>
 2 
 3 class Test  4 {  5 private:  6     const int ci;  7 public:12     int getCI() 13  { 14         return ci; 15  } 16 }; 17 
18 
19 int main() 20 {  
25     return 0; 26 }

上面的程序可以編譯成功,說明類中可以定義const成員。

接下來再看:

 1 #include <stdio.h>
 2 
 3 class Test  4 {  5 private:  6     const int ci;  7 public:
12 int getCI() 13 { 14   return ci; 15 } 16 }; 17 18 19 int main() 20 { 21 Test t; 23 printf("t.ci = %d\n", t.getCI()); 24 25 return 0; 26 }

編譯時會出錯:

21:error: structure 't' with uninitialized const members

在類中可以定義const成員變量,但是通過類來定義對象的時候就會報錯。提示有未初始化的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 }

編譯又出錯了,提示:

8: error: uninitialized member 'Test::ci' with 'const' type 'const int'
10:error: assigment of read-only data-member 'Test::ci'

ci 是只讀的,不能放在賦值號的左邊。

可以得出一個結論,如果要初始化const成員變量,就得在第8行進行。那么在第8行如何進行呢?此時初始化列表就需要閃亮登場了

C++中提供了初始化列表對成員變量進行初始化
語法規則
ClassName::ClassName() :
        m1(v1), m2(v1,v2), m3(v3)
{
  // some other initialize operation
}

 1 #include <stdio.h>
 2 
 3 class Test  4 {  5 private:  6     const int ci;  7 public:  8     Test() : ci(10)  9  { 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 }

 初始化列表(中)

注意事項:
成員的初始化順序成員的聲明順序相同
成員的初始化順序初始化列表中的位置無關
初始化列表先於構造函數的函數體執行

舉例說明:
ClassName::ClassName() :
    m1(v1),m2(v1,v2),m3(v3)
{

}
在初始化列表中m1,m2,m3的順序是這樣排列的,但是這並不意味着m1先於m2進行初始化,m2先於m3進行初始化。
因為:成員的初始化順序與成員的聲明順序相同,與初始化列表中的位置無關

實驗分析:

 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 }

該實驗表明:

類中的成員變量必須通過初始化列表來進行初始化(說的是初始化,不是賦值哦)

成員的初始化順序與初始化列表中的位置無關
初始化列表先於構造函數的函數體執行

初始化列表(下)

類中的const成員
類中的const成員會被分配空間的
類中的const成員的本質是只讀變量
類中的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); //將const屬性去掉,就用const_cast這個屬性。
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成員變量必須在初始化列表中指定初值
const成員變量為只讀變量


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM