• 第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成员变量为只读变量

  • 相关阅读:
    phpize使用方法
    PHP安装redis扩展
    lnmp 搭建后,nginx下php文件404但是html文件正常访问
    nginx配置https访问安装ssl证书
    Linux安装git最新版本
    微信公众号开发处理微信昵称带图片问题
    如何撰写技术文档
    Asp.Net Core 2.0实现HttpResponse中繁切换
    EF6.0 下sql语句自动生成的参数类型decimal(18,2)修改
    Windows注册表详解
  • 原文地址:https://www.cnblogs.com/-glb/p/11809206.html
Copyright © 2020-2023  润新知