比昂写道:-
对于类型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;
}每次运行我的程序时,这个程序的输出都是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;
}在阅读了答案之后,我提供了一个默认的构造函数,但是现在n正在获取垃圾值,但是根据答案,它应该是0,因为m超出了任何其他构造函数的范围,并且它是响应中提到的值初始化。
发布于 2012-02-18 05:36:29
您所看到的行为是为您的类定义的。
如何&为什么行为定义良好?
规则是:
如果不提供无参数构造函数,编译器将为程序生成一个构造函数,以防程序需要。
警告:
如果程序为类定义了任何构造函数,则编译器不会生成无参数构造函数。
根据C++标准,可以通过以下三种方式初始化对象:
当类型名称或构造函数初始化器后面跟着()时,初始化是通过值初始化进行的。
因此,
date any =date();
^^^值初始化一个无名对象,然后将其复制到本地对象any中,同时:
date any;将是默认初始化。
值初始化给任何构造函数无法访问的成员提供初始值为零。
在您的程序中,n和m超出了任何构造函数的范围,因此被初始化为0。
对编辑问题的回答:
在您所编辑的示例中,您的类提供了一个无参数构造函数date(),它能够(&应该)初始化成员n和m,但是这个构造函数没有初始化两个成员,因此在这种情况下不进行零初始化,并且对象中未初始化的成员具有一个date()随机)值,而且这个临时对象被复制到显示不确定的成员值的any对象中。
为斯坦德赛球迷:
对象初始化的规则恰当地定义在:
C++03标准8.5/5:
要zero-initialize,T类型的对象意味着: -如果T是标量类型(3.9),则将对象设置为转换为T的0(0)值; -如果T是非并类类型,则每个非静态数据成员和每个基类子对象都为零初始化; -如果T是一个联合类型,则对象的第一个命名数据成员为零初始化; -如果T是数组类型,则每个元素都为零初始化; -如果T是引用类型,则不执行初始化。要default-initialize,T类型的对象意味着: -如果T是非POD类类型(第9条),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化不正确); -如果T是数组类型,则每个元素都是默认初始化的; -否则,对象将为零初始化。 要value-initialize,T类型的对象意味着: -如果T是具有用户声明的构造函数(12.1)的类类型(第9条),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的); -如果T是一个没有用户声明的构造函数的非联合类类型,那么T的每个非静态数据成员和基类组件都是值初始化的; -如果T是数组类型,则每个元素都是值初始化的; -否则,对象将为零初始化。
发布于 2012-02-18 05:36:20
因为编译器,在它的呼吸下诅咒,为你产生一个。
编辑:既然Als说它不回答问题,我会详细说明。使用date any = date();时,调用编译器生成的默认构造函数。此构造函数调用所有基类和数据成员的默认构造函数。对于您的数据成员,int默认构造函数是int(),它将值设置为0。这是ideone.com上的代码
#include <iostream>
int main( void )
{
int i = -123;
i = int();
std::cout << i << std::endl;
return( 0 );
}程序输出:
0发布于 2012-02-18 05:38:59
来自C++标准草案(1996年12月工作文件):
如果没有类X的用户声明构造函数,则默认构造函数将被隐式声明.隐式声明的默认构造函数是其类的内联公共成员。
https://stackoverflow.com/questions/9338881
复制相似问题