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



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

我用这个来继承。

struct Parent {
    int a;
};
struct Child : Parent {
    int b;
    Child () {
        printf("child constructorn");
    }
}
int main () {
    Child c;
    printf("%dn", c.a);        // c.a = dummy value
    printf("%dn", c.b);        // c.b = 0
    return 0;
}

在上面的代码中,c.a是伪值。然而,当我更改Child构造函数时,它为零。唯一的区别是Child在其构造函数中显式调用父级的构造函数。

struct Parent {
    int a;
};
struct Child : Parent {
    int b;
    Child () : Parent () {
        printf("child constructorn");
    }
}
int main () {
    Child c;
    printf("%dn", c.a);        // c.a = 0
    printf("%dn", c.b);        // c.b = 0
    return 0;
}

会发生什么?我花了一些时间,但找不到任何理由。我使用的编译器是VS2008。提前谢谢。

ParentPOD类型(普通的旧数据类型)。它没有构造函数或析构函数(除了隐式的,它们是琐碎的)、复杂的成员等。它只是一个带有标量或其他POD类型成员的结构。当你这样做时:

struct Child : Parent 
{
    int b;
    Child () {
        printf("child constructorn");
    }
}

您只是在构造子对象。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 constructorn");
    }
}

发生了一些不同的情况:您正在调用Parent基类型的值初始化。由于()

C++11§8.5,p10

初始值设定项是一组空括号的对象,即(),应为值初始化

对于POD类型(Parent是其中之一),值初始化最终将零初始化成员。

C++11§8.5,p7

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

  • 如果T是一个(可能是cv限定的)类类型(第9条),具有用户提供的构造函数(12.1),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化形式不正确);

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

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

  • 否则,对象初始化为零。

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

根据C++标准

11初始化器是一组空括号的对象。,(),应进行值初始化。

8值初始化T类型的对象意味着:--如果T是(可能cv限定)类类型,没有用户提供或删除默认值构造函数,则对象为零初始化

所以在代码片段中

struct Parent {
    int a;
};
struct Child : Parent {
    int b;
    Child () : Parent () {
        printf("child constructorn");
    }

class Parent初始化为零。其标量类型的成员(即数据成员a)已初始化为零。}

最新更新