【问题标题】:Why do const variables have to be initialized right away?为什么 const 变量必须立即初始化?
【发布时间】:2012-01-16 10:39:11
【问题描述】:

这是一个通用的编程问题。我正在学习 C++,我了解到任何 const 变量,即:const int iint *const ptr,都必须立即初始化。

这也是地址引用必须立即初始化的根本原因,因为地址是const

但我找不到必须这样做的原因/为什么要强制执行此规则。

谁能帮我解释一下?

【问题讨论】:

    标签: c++ reference initialization constants


    【解决方案1】:

    当一个变量被声明为 const 时,这意味着该变量是只读的,并且不能被改变。所以为了使一个变量只读,它应该在它被声明的时候被初始化。

    为了更好地理解变量,请查看以下程序

    每个进程基本上由进程运行时可以访问的 4 个地址空间部分组成

    文本 - 这部分包含要执行的实际 m/c 指令。在许多操作系统上,这被设置为只读,因此进程无法修改其指令。这允许程序的多个实例共享文本的单个副本。

    数据 - 这部分包含程序的数据部分。又分为

    1) 初始化只读数据 - 这包含由程序初始化的数据元素,它们在进程执行期间是只读的。

    2) Initialized Read Write Data - 这包含由程序初始化并在流程执行过程中被修改的数据元素。

    3) 未初始化的数据 - 这包含程序未初始化的元素,并且在进程执行之前设置为 0。这些也可以修改并称为 BSS(块开始符号)。这些元素的好处是,系统不必在程序文件中为这个区域分配空间,因为它在进程开始执行之前被操作系统初始化为0。

    堆栈 - 这部分用于局部变量,堆栈帧

    堆 - 这部分包含动态分配的内存

    int abc = 1;                            ---->   Initialized Read-Write Data
    char *str;                              ---->   BSS
    const int i = 10;                       ----->  Initialized Read-Only Data
    
    main()
    {
        int ii,a=1,b=2,c;                            ----->  Local Variables on 
    Stack
    
        char *ptr;
        ptr = malloc(4);                     ------> Allocated Memory in Heap
    
         c= a+b;                             ------> Text
    
    }
    

    数据,存储数据文本,存储代码

    链接器生成的文件有 3 个(主要?)段/部分。 text - 程序文本(显然是 const char 数组。也许是其他 'const' 数组,因为无论如何都无法更改)。我不是 100% 确定数组部分,也许有人会纠正我。

    data - 初始化的全局数据。见下面的例子。 bss - 未初始化的全局数据。下面是一些例子

    int x = 1;    /* goes into data */
    int y;        /* goes into bss  */
    const int z = 1;/* goes into text */
    

    这个,我们已经看到进入“文本”,因为无论如何都无法更改,但可以受到保护

    【讨论】:

      【解决方案2】:

      因为您无法在以后对其进行初始化或赋值。

      const int size; //no initialization (error)
      
      size = 100; //error - you cannot assign a const variable.
      

      现在,如果一个变量既没有任何有意义的值,也因为它是一个 const 变量,你以后也不允许使它具有值,那么这样一个变量的意义何在?完全没用。

      但是,这仅适用于内置和 POD 类型:

      struct A{}; //POD type
      struct B{ B(){} }; //Non POD type because it has user-defined constructor!
      
      const int i; //error - built-in type
      const A a;   //error - POD type
      const B b;   //ok -    Non POD type
      
      //likewise
      const std::string s; //ok - std::string is a non-POD
      const std::vector<std::string> v; //ok - std::vector is a non-POD
      

      实际上一个非 POD 类型不能保持未初始化,因为会调用默认构造函数,并且对象会被初始化。


      现在考虑这个结构,

      struct C
      {
         const int i;
         C() {}
      };
      

      C 绝对是非 POD 类型,因为它有用户定义的构造函数。另请注意,在构造函数中,它不会初始化 i,即int,声明为const。因为这个未初始化的const i,下面会报错:

      const C c; //error - 
      

      有人可能会认为错误是因为上面声明的变量c 中的const。但这是短视的,不是真的。即使删除const,也会报错:

      C c; //error - same error
      

      错误是因为C::i 声明为const 但尚未初始化。

      演示:http://ideone.com/NJT8L


      该分析还表明,内置类型不会自动初始化,即使它们是非 POD 类型的成员。非 POD 类类型也是如此。

      内置类型(和 POD 类型)的 default 初始化语法如下:

      struct C
      {
          const int i;
          C() : i() {} //note the syntax - it is called member-initialization list
      };
      

      现在这是允许的:

      C x; //ok
      const C y; //ok
      

      演示:http://ideone.com/84vD9


      至于什么是结构/类 POD,请参阅此主题:

      【讨论】:

      • 不 const int 大小;使用 int 的默认构造函数(即为 0)初始化 size 呢?
      • 顺便说一句,一旦计时器允许,我就会给你的答案打勾。在编写“int i;”时,i 使用默认构造函数初始化为 0。为什么不使用带有 const 的默认构造函数?也许这应该是一个单独的问题......
      • @Lebowski156: int i 不会初始化为 0(如果它是局部变量),规范不保证这一点。但是,如果您在命名空间级别写入int i,那么它会静态地 初始化为0。但是当您将其设为const 变量时,您会报错。这就是语言规范定义行为的方式。
      • "此分析还表明,内置类型确实会自动初始化,即使它们是非 POD 类型的成员。" ???
      • @curiousguy:这是一个错字。应该有一个。我刚刚更正了。
      【解决方案3】:

      不允许在程序中为 const 变量赋值,因为那样你可能会改变它的值,这显然是错误的!!!!

      因此,您需要初始化它们..

      希望对你有帮助

      【讨论】:

        【解决方案4】:

        因为如果您以后可以分配给它们,它们就不会是“const”。

        【讨论】:

        • 我认为“稍后”在这里有点误导。似乎const 变量的重要属性是它只能被分配一次。因此,如果它可以在分配发生后进行分配,那么它就不会是const。但没有什么要求在声明时进行分配。所以我认为 OP 要问的是,为什么初始分配必须作为声明的一部分发生?
        • @aroth:为了迂腐,const 变量不能永远被赋值。并回答您的观点;你把声明和定义混为一谈了。
        • 作为一个有趣的旁注(本着这是一个通用编程问题的精神),Java 确实允许在初始声明之后分配 final 变量。但只有一次。
        • @aroth "const 变量的重要属性" 定义 "const 变量"
        猜你喜欢
        • 2020-05-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多