简体   繁体   English

C++ 零初始化

[英]C++ Zero-Initialization

I'm having trouble understanding when and why exactly a member in my class is zero-initialized according to http://en.cppreference.com/w/cpp/language/zero_initialization .根据http://en.cppreference.com/w/cpp/language/zero_initialization ,我无法理解我班级中的某个成员何时以及为何被零初始化。

Consider the following test program:考虑以下测试程序:

#include <iostream>
#include <stdio.h>

class MyTest {
private:
    const static unsigned int dimension = 8;
    void (* myFunctions [dimension])();

public: 
    MyTest() {}

    void print() { 
        for(unsigned int i=0; i < MyTest::dimension; i++) {
            printf("myFunctions[%d] = %p\n", i, this->myFunctions[i]);
        }   
    }
};


int main() {
    //We declare and initialize an object on the stack 
    MyTest testObj = {};
    testObj.print();

    return 0;
}

I am declaring a class to have an array of 8 function pointers of the signature "void functionname()".我正在声明一个类,该类具有签名为“void functionname()”的 8 个函数指针数组。 When I declare and initialize an object of the class in main as MyTest testObj = {};当我在main声明并初始化类的一个对象时,作为MyTest testObj = {}; or MyTest testObj;MyTest testObj; , I expected it to be zero-initialized, ie all pointers are null pointers. ,我希望它是零初始化的,即所有指针都是空指针。

However, compiling with g++ 5.3.0 on my Windows 10 machine with g++ -m32 -o test -std=c++14 test.cpp && test machine gives the output:但是,使用g++ -m32 -o test -std=c++14 test.cpp && test machine 在我的 Windows 10 机器上使用 g++ 5.3.0 编译给出输出:

myFunctions[0] = 76dd6b7d
myFunctions[1] = 00401950
myFunctions[2] = 0061ff94
myFunctions[3] = 004019ab
myFunctions[4] = 00401950
myFunctions[5] = 00000000
myFunctions[6] = 003cf000
myFunctions[7] = 00400080

Which look like un-initialized values from the stack..看起来像堆栈中未初始化的值..

If I move the declaration of the object outside of main (as a global variable), it prints all zeroes again.如果我将对象的声明移到 main 之外(作为全局变量),它会再次打印全零。

If I have understood cppreference correctly, this is because I have a variariable with static storage duration, and is thus zero-initialized.如果我正确理解了 cppreference,这是因为我有一个具有静态存储持续时间的变量,因此是零初始化的。 It initializes my class type by zero-initializing all non-static data members of my class (ie, the myFunctions ) array.它通过零初始化我的类(即myFunctions )数组的所有非静态数据成员来初始化我的类类型。 An array is initialized by zero-initializing every element of it, which, in my function pointer case, is a null pointer.一个数组是通过零初始化它的每个元素来初始化的,在我的函数指针情况下,它是一个空指针。

Why does it not zero-initialize my object the stack when I declare it with MyTest testObj = {};为什么当我用MyTest testObj = {};声明我的对象时,它不会将我的对象初始化为零MyTest testObj = {}; ? ?

The following以下

MyTest testObj = {};

is not zero-initialization for MyTest , but is simply calling its default constructor.不是MyTest零初始化,而是简单地调用其默认构造函数。 The cppreference page explains why (emphasis mine): cppreference页面解释了原因(重点是我的):

As part of value-initialization sequence for non-class types and for members of value-initialized class types that have no constructors , including value initialization of elements of aggregates for which no initializers are provided.作为非类类型和没有构造函数的值初始化类类型成员的值初始化序列的一部分,包括未提供初始化器的聚合元素的值初始化。

MyTest is a class type, and a has a constructor. MyTest是一个类类型,并且 a 有一个构造函数。


Defining the constructor with定义构造函数

MyTest() = default;

will instead zero-initialize the object.将改为对对象进行零初始化

Relevant Standard quotes (emphasis mine) below.相关标准报价(强调我的)如下。

From [dcl.init#8] :来自[dcl.init#8]

To value-initialize an object of type T means:对 T 类型的对象进行值初始化意味着:

  • if T is a (possibly cv-qualified) class type with either no default constructor ([class.ctor]) or a default constructor that is user-provided or deleted, then the object is default-initialized;如果 T 是(可能是 cv 限定的)类类型,没有默认构造函数 ([class.ctor]) 或用户提供或删除的默认构造函数,则该对象是默认初始化的;

  • if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;如果 T 是(可能是 cv 限定的)类类型而没有用户提供或删除的默认构造函数,则对象被零初始化并检查默认初始化的语义约束,并且如果 T 具有非平凡的默认构造函数, 对象是默认初始化的;

  • ... ...

From [dcl.init.list] :来自[dcl.init.list]

List-initialization of an object or reference of type T is defined as follows:类型 T 的对象或引用的列表初始化定义如下:

  • ... ...

  • Otherwise, if the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.否则,如果初始化列表没有元素并且 T 是具有默认构造函数的类类型,则对象是值初始化的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM