• C++中初始化列表的使用(总结)


    原文链接 https://www.cnblogs.com/dishengAndziyu/p/10906081.html

    参考链接:https://www.cnblogs.com/laiqun/p/5776212.html 

                      https://blog.csdn.net/zzyczzyc/article/details/87542418

                     https://www.cnblogs.com/cthon/p/9178701.html

                    http://blog.sina.com.cn/s/blog_4c79cc450100lkzh.html

     

    1,初始化列表是在 C++ 中才引入的;

    2,以“类中是否可以定义 const 成员?”这个问题来引入初始化列表:

        1,const 这个关键字可以定义真正意义上的常量,也可以在某些情况下定义只读变量;

     

    3,小实验:

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

    复制代码
    复制代码
     1 #include <stdio.h>
     2 
     3 class Test
     4 {
     5 private:
     6     const int ci;  // const 作用于 C++ 中的成员变量后得到的是只读成员变量,只读成员变量是不可以出现在成员符号左边的;所以会出现第 10 行的错误信息;
     7 public:
     8 /*
     9     Test()  // 在这里编译器显示:ci 是一个 const 成员,没有进行初始化;因此如果要初始化 ci 成员变量,必须要在这一行进行,这个时候就让初始化列表出厂了;
    10     {       
    11         ci = 10;  // 在这里编译器显示:ci 在这个类中是一个只读的成员变量;
    12     }
    13 */
    14 
    15     /* 由上面的语句改换如下 */
    16     Test() : ci(10)  // ci 在初始化之后可以改变,因为 ci 在这里只是一个只读的成员变量,仅仅是不能出现在赋值符号左边而已;我们依旧可以通过指针的方式来修改 ci 里面的值;
    17     {
    18         // ci = 10;
    19     }
    20        
    21     int getCI() 
    22     { 
    23         return ci; 
    24     }
    25 };
    26 
    27 int main()
    28 {
    29     Test t;  // 当这里没有手工定义上面程序中的无参构造函数的时候,显示有“未初始化的 const 的成员”的错误; 同时的当这里没有通过类来定义对象的时候,可以通过编译,说明 const 可以修饰 C++ 中的成员变量;
    30     
    31     printf("t.ci = %d
    ", t.getCI());
    32     
    33     return 0;
    34 }
    复制代码
    复制代码

     

    4,C++ 中提供了初始化列表对成员变量进行初始化,其语法规则为:

        1,代码示例:

    1 ClassName::ClassName() : m1(v1), m2(v1, v2), m3(v3)  // 用 v1, (v1, v2), v3 分别对 m1, m2, m3 初始化; 
    2 {
    3        // some other initialize operation;
    4 }

           1,初始化列表应该在构造函数的地方使用;

           2,构造函数参数列表之后函数体之前定义初始化列表;

           3,其作用就是对成员变量进行初始化;

        2,注意事项(避免 bug 很重要):

           1,成员的初始化顺序与成员的声明顺序相同;

           2,成员的初始化顺序与初始化列表中的位置无关;

           3,初始化列表先于构造函数的函数体执行;

               (1)当构造函数的函数体开始执行的时候,对象已经创建完毕了,执行构造函数的函数体仅仅是为了初始化我们这个对象的状态而已;

               (2)所以说初始化列表既然是用于初始化,那么必须在我们这个类对象创建的同时来进行执行,而不应该是对象已经创建好了才来进行一系列的初始化工作,这一点是有明确差异的,这个差异也就是初始化和赋值之间的差异;  

    5,初始化列表的使用编程实验:

    复制代码
    复制代码
     1 #include <stdio.h>
     2 
     3 class Value
     4 {
     5 private:
     6      // int mi = 0;  // 要初始化成员变量,只能使用初始化列表;在构造函 数当中的那是对成员变量赋值,不是初始化;  
     7  
     8       int mi;
     9     
    10 public:
    11     Value(int i)
    12     {
    13         printf("i = %d
    ", i);
    14         mi = i;
    15     }
    16     
    17     int getI()
    18     {
    19         return mi;
    20     }
    21 };
    22 
    23 class Test
    24 { 
    25 private:
    26 /*
    27     Value m2(2);  // 这种明确的调用一个参数的方式也是有语法错误的;
    28     Value m3(3);
    29     Value m1(1);
    30 */  
    31     Value m2;
    32     Value m3;
    33     Value m1;
    34     
    35 public:
    36 /*
    37     Test()  // 这里编译器显示没有 value 类的无参构造函数来匹配调用;
    38     {
    39     
    40     }
    41 */
    42     Test() : m1(1), m2(2), m3(3)  // 成员变量的初始化必须通过初始化列表来完成;
    43     {
    44         printf("Test::Test()
    ");  // 初始化列表先于构造函数的函数体执行;
    45     }
    46 };
    47 
    48 int main()
    49 {
    50     Test t;
    51     
    52     return 0;
    53 }
    复制代码
    复制代码

    6,类中的 const 成员:

        1,类中的 const 成员会被分配空间的;在这里注意:(只有编译时 用立即数初始化的才是真的常量,const成员在编译时 没法直接赋值,能不能进符号表 就看编译时是否可以直接知道值,类只是一个模子  所以不可能给模子赋值  只有在创建对象时才可能  因为创建对象时是分配空间的时候)

         (1)const 成员分配的空间和我们整个类对象分配的空间一致;

        2,类中的 const 成员的本质是只读变量;

         (1)根据编译提供的错误 bug 信息而得来;

        3,类中的const 成员只能在初始化列表中指定初始值;

             (1)编译器无法直接得到 const 成员的初始值,因此无法进入符号表成为真正意义上的常量;

             (2)  运行时才来定义对象申请空间,调用构造函数,继而来调用初始化列表初始化成员变量; 

    7,只读成员变量编程实验:

      1,代码示例:

    复制代码
    复制代码
     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     
    24     Value m2;
    25     Value m3;
    26     Value m1;
    27     
    28 public:
    29     Test() : m1(1), m2(2), m3(3), ci(100)
    30     {
    31         printf("Test::Test()
    ");
    32     }
    33     
    34     int getCI()
    35     {
    36         return ci;
    37     }
    38     
    39     int setCI(int v)
    40     {
    41         int* p = const_cast<int*>(&ci);  // 通过指针来操作常量对象;
    42         
    43         *p = v;
    44     }
    45 };
    46 
    47 
    48 int main()
    49 {
    50     Test t;
    51     
    52     printf("t.ci = %d
    ", t.getCI());
    53     
    54     t.setCI(10);
    55     
    56     printf("t.ci = %d
    ", t.getCI());
    57     
    58     return 0;
    59 }
    复制代码
    复制代码

       这个实验说明:类中的 const 成员不是真正意义上的常量,它只是只读变量(编译器告诉的);

    8。小插曲:

        1,初始化与赋值不同:

           1,初始化:对正在创建的对象进行初始值设置;初始化的时候,对象还没创建好,在创建的同时,我们将它的值确定了;

           2,赋值:对已经存在的对象进行值设置;

    复制代码
    1 int main()
    2 {
    3     int i = 0;  // 这是初始化,初始化的时候 i 还不存在;
    4     // ...
    5     i = 0;  // 这是赋值, i 是实际存在的了,并且 i 已经有一个值了,这个时候将 i 的值被改变了
    6 }

    9,小结:

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

           (1)类中不能直接初始化成员变量(不论变量为一般的还是类的对象),只能通过初始化列表来初始化;

        2,初始化列表先于构造函数体执行;

        3,类中可以定义 const 成员变量(这里是变量);

          (1)const 作用于类的成员后得到的仅是只读变量;

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

        5,const 成员变量为只读变量;

  • 相关阅读:
    .net中使用事务 dodo
    dnn中NULL值的处理 dodo
    通过sql server的作业调度+存储过程来实现系统定时任务的方法 dodo
    使用With...End With dodo
    ASP.NET页面中使用SolpartMenu控件 dodo
    浅解web打印 dodo
    WEB打印大全(转) dodo
    AjaxMethod未定义原因 dodo
    CommandEventArgs.CommandArgument 属性 dodo
    在用VS.NET2003 新建项目时系统提示 autometion服务器无法创建对象 这是什么问题? dodo
  • 原文地址:https://www.cnblogs.com/zhj868/p/14258499.html
Copyright © 2020-2023  润新知