两种调用默认构造函数的方法

mt_*_*erg 5 c++ constructor

我有以下代码:

struct B
{
 //B() {}
 int x;
 int y;
};

void print(const B &b) 
{
 std::cout<<"x:"<<b.x<<std::endl;
 std::cout<<"y:"<<b.y<<std::endl;
 std::cout<<"--------"<<std::endl;
}

int main()
{
 B b1 = B(); //init1
 B b2; //init2

 print(b1);
 print(b2);

 return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我启动程序(vs2008,调试)时,我有以下输出:

x:0
y:0
--------
x:-858993460
y:-858993460
--------
Run Code Online (Sandbox Code Playgroud)

如您所见,b1.x和b1.y的值为0.为什么?init1和init2有什么区别?

当我取消注释B构造函数时,我有以下输出:

x:-858993460
y:-858993460
--------
x:-858993460
y:-858993460
--------
Run Code Online (Sandbox Code Playgroud)

有人可以解释这种行为的原因吗?Tnx提前.

Kir*_*sky 10

POD类型的默认构造函数用零填充它.当您明确定义自己的构造函数时,您不会初始化x并且y您将获得随机值(在VS调试中,它们将填充精确值,但在发布时它们将是随机的).

它符合C++ 03标准8.5/5:

<...> 对类型为T的对象进行值初始化意味着:
- 如果T是具有用户声明的构造函数(12.1)的类类型(第9节),则调用T的默认构造函数(并且初始化为如果T没有可访问的默认构造函数,则格式错误);
- 如果T是没有用户声明的构造函数的非联合类类型,则T的每个非静态数据成员和基类组件都是值初始化的;
- 如果T是数组类型,则每个元素都是值初始化的;
- 否则,对象被零初始化.

B()是临时的值初始化,将用于复制初始化b1.

B b2没有为对象指定的初始化程序中,因此根据C++ 03 Standard 8.5/9:

如果没有为对象指定初始化程序,并且该对象是(可能是cv限定的)非POD类类型(或其数组),则该对象应默认初始化; 如果对象是const限定类型,则底层类类型应具有用户声明的默认构造函数. 否则,如果没有为非静态对象指定初始化程序,则该对象及其子对象(如果有)具有不确定的初始值 ; 如果对象或其任何子对象是const限定类型,则程序格式错误.

b2你写零可以写B b2 = {};.


CB *_*ley 5

在这两种情况下,这条语句定义B1和复制intializes从它的值初始化临时B对象.

B b1 = B();
Run Code Online (Sandbox Code Playgroud)

B没有用户声明的构造函数时,值初始化会导致调用B成员的值为初始,对于简单类型,例如int,这意味着零初始化.

什么B时候有用户声明的构造函数,value-initializing尝试调用默认构造函数.如果成员xy没有在构造函数初始化列表中列出,那么它们将保持未初始化状态.

B b2;
Run Code Online (Sandbox Code Playgroud)

在函数中,没有初始化器的POD类型的本地对象保持未初始化.当您没有为其定义构造函数时B,它是一个POD类,因此这适用,并且值的值b2.xb2.y不确定值.

如果对象是非POD类类型,那么它是默认初始化的,但是如果它调用一个构造函数,使其成员保持未初始化状态,那么这没有区别.