代码之家  ›  专栏  ›  技术社区  ›  Bill

下面的短语在C++中意味着什么:零、缺省值和值初始化?

  •  172
  • Bill  · 技术社区  · 16 年前

    下面的短语在C++中意味着什么:

    • 零初始化,

    • 默认初始化,以及

    • 值初始化

    C++开发者应该知道什么?

    2 回复  |  直到 10 年前
        1
  •  59
  •   Community Mohan Dere    9 年前

    有一件事要认识到,“价值初始化”是新的与C++ 2003标准-它不存在于原来的1998标准(我认为这可能是唯一的区别,这不仅仅是一个澄清)。见 Kirill V. Lyadvinsky's answer 对于直接来自标准的定义。

    关于 operator new 关于这些类型初始化的不同行为以及当它们进入(以及当它们不同于C++ 98到C++ 03时)的细节:

    答案的要点是:

    有时,新运算符返回的内存将被初始化,有时,它将不取决于您要更新的类型是pod,还是它是一个包含pod成员并使用编译器生成的默认构造函数的类。

    • 在C++ 1998中,初始化有2种类型:零和默认值。
    • 在C++ 2003中进行了第三种初始化,增加了值初始化。

    至少可以说,这是相当复杂的,而且当不同的方法进入时是微妙的。

    需要注意的一件事是MSVC遵循C++ 98规则,甚至在VS 2008(VC 9或C.exe版本15 .x)中。

    下面的代码片段表明,数字签名和数字火星遵循C++ 98规则,而GCC和C则遵循C++ 03规则:

    #include <stdio.h>
    #include <string.h>
    #include <new>
    
    struct A { int m; }; // POD
    struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
    struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m
    
    int main()
    {
        char buf[sizeof(B)];
        memset( buf, 0x5a, sizeof( buf));
    
        // use placement new on the memset'ed buffer to make sure 
        //  if we see a zero result it's due to an explicit 
        //  value initialization
        B* pB = new(buf) B();   //C++98 rules - pB->m is uninitialized
                                //C++03 rules - pB->m is set to 0
        printf( "m  is %d\n", pB->m);
        return 0;
    }
    
        2
  •  82
  •   Kirill V. Lyadvinsky    16 年前

    C++ 03标准85/5:

    到 零初始化 T类物体是指:
    如果t是标量类型(3.9),则将对象设置为0(零)的值转换为t;
    –如果t是非联合类类型,则每个非静态数据成员和每个基类子对象初始化为零;
    如果t是联合类型,则第一个命名为data member的对象初始化为零;
    如果t是数组类型,则每个元素初始化为零;
    如果t是引用类型,则不执行初始化。

    到 默认初始化 T类物体是指:
    如果t是非pod类类型(第9条),则调用t的默认构造函数(如果t没有可访问的默认构造函数,则初始化是不正确的);
    –如果t是数组类型,则每个元素都是默认初始化的;
    否则,对象初始化为零。

    到 值初始化 T类物体是指:
    –如果t是具有用户声明的构造函数(12.1)的类类型(第9条),则调用t的默认构造函数(如果t没有可访问的默认构造函数,则初始化是不正确的);
    如果t是没有用户声明的构造函数的非联合类类型,则t的每个非静态数据成员和基类组件都是值初始化的;
    如果t是数组类型,则每个元素都是值初始化的;
    否则,对象初始化为零

    调用引用类型实体的默认初始化或值初始化的程序格式错误。如果t是cv限定类型,则t的cv非限定版本用于这些零初始化、默认初始化和值初始化的定义。