• 12 初始化列表


    1 问题引入

    • 问题:类中是否可以定义 const 成员?

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

      • Demo

        #include <stdio.h>
        
        class Test
        {
        private:
            const int ci;
        public:
            int getCI() 
            { 
                return ci; 
            }
        };
        
        int main()
        {
            Test t;
            
            printf("t.ci = %d
        ", t.getCI());
            
            return 0;
        }
        
      • 编译

        test.cpp: In fuction 'int main()':
        test.cpp:14: error: structure 't' with uninitialized const members
        
      • 说明:类中可以定义 const 成员,但通过这个类类型定义对象时,编译器会报错:会对该 const 成员进行初始化

      • 修改:利用构造函数进行 const 成员的初始化

        #include <stdio.h>
        
        class Test
        {
        private:
            const int ci;
        public:
            Test()
            {
                ci = 10;
            }
            int getCI() 
            { 
                return ci; 
            }
        };
        
        int main()
        {
            Test t;
            
            printf("t.ci = %d
        ", t.getCI());
            
            return 0;
        }
        
      • 编译

        test.cpp: In constructor 'Test::Test()':
        test.cpp:8: error: uninitialized member 'Test::ci' with 'const' type 'const int'
        test.cpp:10: error: assignment of read-only data-member 'Test::ci'
        
      • 说明:类的 const 成员必须用列表初始化

    2 类成员的列表初始化

    • C++ 中提供了初始化列表对成员变量进行初始化

    • 语法规则

      ClassName::ClassName(): m1(v1),m2(v1,v2),m3(v3)
      {
          //some other initialize operator
      }
      
    • 注意事项

      • 成员的初始化顺序与成员的声明顺序相同

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

        • 虽然 m1 在前,但 m1 的初始化不一定在 m2m3 之前,依赖于它们的声明顺序
        ClassName::ClassName(): m1(v1),m2(v1,v2),m3(v3)
        {
            //some other initialize operator
        }
        
      • 初始化列表先于构造函数的函数体执行

        • 当构造函数的函数体执行的时候,类的对象已经构建完毕,执行构造函数的函数体只是为了初始化这个对象的状态而已
        • 列表初始化是为了初始化,是在类的对象创建之前执行的,这是初始化和赋值之间的差异
    • 示例:初始化列表的使用

      • Demo

        #include <stdio.h>
        
        class Value
        {
        private:
            int mi;
        public:
            Value(int i)
            {
                printf("i = %d
        ", i);
                mi = i;
            }
            int getI()
            {
                return mi;
            }
        };
        
        class Test
        {
        private:
            Value m2;
            Value m3;
            Value m1;
        public:
            Test() : m1(1), m2(2), m3(3)   //类的类类型成员必须使用列表初始化
            {
                printf("Test::Test()
        ");
            }
        };
        
        int main()
        {
            Test t;
            
            return 0;
        }
        
      • 编译运行

        i = 2
        i = 3
        i = 1
        Test::Test()
        

    3 类中的 const 成员

    • 类的 const 成员会被分配空间

    • 类的 const 成员的本质是只读变量

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

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

    • 示例:只读成员变量

      • Demo

        #include <stdio.h>
        
        class Value
        {
        private:
            int mi;
        public:
            Value(int i)
            {
                printf("i = %d
        ", i);
                mi = i;
            }
            int getI()
            {
                return mi;
            }
        };
        
        class Test
        {
        private:
            const int ci;
            Value m2;
            Value m3;
            Value m1;
        public:
            Test() : m1(1), m2(2), m3(3), ci(100)
            {
                printf("Test::Test()
        ");
            }
            int getCI()
            {
                return ci;
            }
            int setCI(int v)
            {
                int* p = const_cast<int*>(&ci);
                
                *p = v;
            }
        };
        
        int main()
        {
            Test t;
            
            printf("t.ci = %d
        ", t.getCI());
            
            t.setCI(10);
            
            printf("t.ci = %d
        ", t.getCI());
            
            return 0;
        }
        
      • 编译运行

        i = 2
        i = 3
        i = 1
        Test::Test()
        t.ci = 100
        t.ci = 10
        
    • 初始化与赋值的不同

      • 初始化:对正在创建的对象进行初值设置
      • 赋值:对已经存在的对象进行值设置
  • 相关阅读:
    datasnap 2010 为DataSnap系统服务程序添加描述
    uLanguage.pas
    cxgrid上如何取FOOTER上合计的值
    cxgrid经典用法
    datasnap 2010 DataSnap服务端和客户端发布分发方法
    php_network_getaddresses: getaddrinfo failed 原因
    查看crontab运行状态
    laravel 开启定时任务需要操作
    解决cron不执行的问题
    UPdate语句
  • 原文地址:https://www.cnblogs.com/bky-hbq/p/13715598.html
Copyright © 2020-2023  润新知