C++ struct默认构造函数行为

jwc*_*hoi 3 c++ constructor struct

据我所知,如果程序员没有实现任何构造函数,编译器会自动生成不执行任何操作的默认构造函数.我认为它也适用于struct.

我用它来继承.

struct Parent {
    int a;
};

struct Child : Parent {
    int b;
    Child () {
        printf("child constructor\n");
    }
}

int main () {
    Child c;
    printf("%d\n", c.a);        // c.a = dummy value
    printf("%d\n", c.b);        // c.b = 0
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,ca是虚拟值.但是,当我更改Child构造函数时,它为零.唯一的区别是Child在其构造函数中显式调用父的构造函数.

struct Parent {
    int a;
};

struct Child : Parent {
    int b;
    Child () : Parent () {
        printf("child constructor\n");
    }
}

int main () {
    Child c;
    printf("%d\n", c.a);        // c.a = 0
    printf("%d\n", c.b);        // c.b = 0
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

怎么了?我花了一些时间但找不到任何理由.我使用的编译器是VS2008.先感谢您.

Who*_*aig 5

ParentPOD类型(普通旧数据类型).它没有构造函数或析构函数(除了隐式的,也是微不足道的),复杂的成员等.它只是一个带有标量或其他POD类型成员的结构.当你这样做:

struct Child : Parent 
{
    int b;
    Child () {
        printf("child constructor\n");
    }
}
Run Code Online (Sandbox Code Playgroud)

你只是构建子对象.没有相关的建设Parent正在进行中.基类型经过默认初始化:

C++11§8.5,p11

如果没有为对象指定初始化程序,则默认初始化该对象; 如果未执行初始化,则具有自动或动态存储持续时间的对象具有不确定的值.[注意:具有静态或线程存储持续时间的对象是零初始化的,请参见3.6.2.

对于您的POD类型,这意味着:

C++11§8.5,p6

默认初始化T类型的对象意味着:

  • 如果T是一个(可能是cv限定的)类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的);

  • 如果T是数组类型,则每个元素都是默认初始化的;

  • 否则,不执行初始化.

但是,当你做这个:

struct Child : Parent 
{
    int b;
    Child () : Parent () {
        printf("child constructor\n");
    }
}
Run Code Online (Sandbox Code Playgroud)

一些不同的情况:你调用值初始化的的Parent基本类型.由于().

C++11§8.5,p10

初始值为空集括号的对象,即(),应进行值初始化.

对于POD类型(其中Parent一个),值初始化最终将成员初始化.

C++11§8.5,p7

对值类型T的对象进行值初始化意味着:

  • 如果T是具有用户提供的构造函数(12.1)的(可能是cv限定的)类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的) ;

  • 如果T是一个(可能是cv限定的)非联合类类型而没有用户提供的构造函数,那么该对象是零初始化的,如果T的隐式声明的默认构造函数是非平凡的,则调用该构造函数.

  • 如果T是数组类型,那么每个元素都是值初始化的;

  • 否则,该对象被零初始化.

因此a在第二种情况下为零,但在第一种情况下不是.(好吧,它在第一个中可能为零,你真的不能说;它的值是不确定的,直到你给它分配东西).