Bjarne写道: -
对于类型T,T()是默认值的表示法,由默认构造函数定义.当我们不声明默认构造函数时会发生什么?例如
using namespace std;
class date{
int n,m;
public:
int day(){return n;}
int month(){return m;}
};//no default constructor
int main()
{
date any =date();
cout<<any.month()<<endl;
cout<<any.day()<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
每次运行程序时,该程序的输出为0和0.我没有声明任何默认构造函数然后为什么会退出默认值,即0?
编辑-
class date{
int n,m;
public:
date (){
m=1;}
int day(){return n;}
int month(){return m;}
};
int main()
{
date any =date();
cout<<any.month()<<endl;
cout<<any.day()<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在阅读答案后,我提供了一个默认构造函数,但现在n正在获取垃圾值但是根据答案它应该是0,因为m是任何其他构造函数都无法接触的,并且它是值初始化,如答案中所述
您看到的行为是为您的班级定义的.
如何以及为什么行为定义明确?
规则是:
如果您不提供无参数构造函数,则编译器会为您的程序生成一个,以防您的程序需要一个.
警告:
如果您的程序为该类定义了任何构造函数,则编译器不会生成无参数构造函数.
根据C++标准,可以通过3种方式初始化对象:
当,类型名称或构造函数初始化程序后面()的初始化是通过值初始化.
从而,
date any =date();
^^^
Run Code Online (Sandbox Code Playgroud)
值初始化无名对象,然后将其复制到本地对象any,同时:
date any;
Run Code Online (Sandbox Code Playgroud)
将是默认初始化.
值初始化为任何构造函数不可及的成员提供零的初始值.
在你的程序中,n并且m超出了任何构造函数的范围,因此被初始化为0.
回答编辑问题:
在你编辑的情况下,你的类提供了一个无参数的构造函数,date()它能够(n并且应该)初始化成员m,但是这个构造函数不会初始化这两个成员,所以在这种情况下不会发生零初始化,并且对象中的未初始化成员具有Indeterminate(任意随机)值,此外,此临时对象将复制到any对象,该对象显示show indeterminate成员值.
对于Standerdese粉丝:
对象初始化的规则适当地定义在:
C++ 03标准8.5/5:
到零初始化类型T的对象是指:
-如果T是一个标量类型(3.9),所述对象被设置为0(零)的值转换至T;
- 如果T是非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的;
- 如果T是联合类型,则对象的第一个命名数据成员为零初始化;
- 如果T是数组类型,则每个元素都是零初始化的;
- 如果T是引用类型,则不执行初始化.到缺省初始化类型T的对象是指:
-如果T是一个非POD类型(第9节),T的默认构造函数被调用(并形成不良的初始化如果T没有可访问的缺省的构造);
- 如果T是数组类型,则每个元素都是默认初始化的;
- 否则,对象被零初始化.到值初始化类型的物体T是指:
-如果T是一个类型(第9节)与用户声明的构造(12.1),然后对T中的默认构造函数被调用(以及初始化是形成不良的如果T没有可访问的默认构造函数);
- 如果T是没有用户声明的构造函数的非联合类类型,则T的每个非静态数据成员和基类组件都是值初始化的;
- 如果T是数组类型,则每个元素都是值初始化的;
- 否则,对象被零初始化