zoukankan      html  css  js  c++  java
  • 第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 ", 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
    ", 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
    ", 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
    ", 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()
    ");
    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
    ", 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()
    ");
    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
    ", t.getCI());
    49     
    50     t.setCI(10);
    51     
    52     printf("t.ci = %d
    ", t.getCI());
    53     
    54     return 0;
    55 }

    初始化与赋值不同
    初始化:对正在创建的对象进行初值设置
    赋值:对已存在的对象进行值设置

    小结:
    类中可以使用初始化列表对成员进行初始化
    初始化列表先于构造函数体执行
    类中可以定义const成员变量
    const成员变量必须在初始化列表中指定初值
    const成员变量为只读变量

  • 相关阅读:
    winform+c#之窗体之间的传值 Virus
    ASP.NET 2.0 利用 checkbox获得选中行的行号, 在footer中显示 Virus
    .NET中的winform的listview控件 Virus
    我的书橱
    Expert .NET 2.0 IL Assembler·译者序一 写在一稿完成之即
    Verbal Description of Custom Attribute Value
    AddressOfCallBacks in TLS
    下一阶段Schedule
    2008 Oct MVP OpenDay 第二天 博客园聚会
    2008 Oct MVP OpenDay 第二天 颁奖·讲座·晚会
  • 原文地址:https://www.cnblogs.com/-glb/p/11809206.html
Copyright © 2011-2022 走看看