C++ 未定义构造函数的默认值

C++ 未定义构造函数的默认值,c++,constructor,C++,Constructor,比亚恩写道:—— 对于类型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(); c

比亚恩写道:——
对于类型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;

}
使用名称空间std;
上课日期{
int n,m;
公众:
int day(){return n;}
int month(){return m;}
};//没有默认构造函数
int main()
{
任何日期=日期();

cout因为编译器会低声咒骂,为您生成一个

编辑:因为Als说它不回答问题,所以我将详细说明。当您使用
dateany=date();
,您将调用编译器生成的默认构造函数。此构造函数为所有基类和数据成员调用默认构造函数。对于您的数据成员
int
默认构造函数为
int()
,它将值设置为
0


您看到的行为是为您的类定义的


行为如何定义以及为什么定义良好?

规则是:
如果您不提供无参数构造函数,编译器将为您的程序生成一个无参数构造函数,以备您的程序需要。
警告:
如果程序为类定义了任何构造函数,则编译器不会生成无参数构造函数

<> P>按照C++标准,一个对象可以用3种方式初始化:

  • 零初始化
  • 默认初始化&
  • 值初始化
当类型名或构造函数初始值设定项后跟
()
时,初始化是通过值初始化完成的

因此,

值初始化一个无名对象,然后将其复制到本地对象
any
, 而:

date any;
将是默认的初始化

值初始化为任何构造函数都无法访问的成员提供初始值零。
在您的程序中,
n
m
超出任何构造函数的能力范围,因此被初始化为
0


对已编辑问题的回答:
在您编辑的案例中,您的类提供了一个无参数构造函数,
date()
,它是有能力的(&should)初始化成员
n
m
,但此构造函数不会同时初始化这两个成员,因此在这种情况下不会发生零初始化,并且对象中未初始化的成员具有不确定的(任意随机)值,该临时对象将进一步复制到显示不确定成员值的任何
对象


对于标准球迷:
对象初始化的规则在中有适当的定义:

C++03标准8.5/5:

零初始化类型为T的对象意味着:
-如果T是标量类型(3.9),则将对象设置为转换为T的0(零)值;
-如果T是非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的;
-如果T是联合类型,则对象的第一个命名数据成员为零初始化;
-如果T是数组类型,则每个元素初始化为零;
-如果T是引用类型,则不执行初始化

默认初始化类型为T的对象意味着:
-如果T是非POD类类型(第9条),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的);
-如果T是数组类型,则每个元素都默认初始化;
-否则,对象初始化为零

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


< C++ >草案标准(1996年12月工作文件):


如果类X没有用户声明的构造函数,则默认构造函数将被隐式声明。隐式声明的默认构造函数是其类的内联公共成员。

@Als是的,它是。请参阅我对您的答案的评论:我接下来要做的是提供一个类似以下内容的默认构造函数`date(){m=1;}`但现在n得到了垃圾值,但它并没有调用int()使n得到垃圾值zero@T.J.
date::date():n(),m(1){}
使用
dateany;
不会初始化它。
dateany=date();
将调用编译器生成的默认构造函数,而默认构造函数又将调用所有基类和成员的默认构造函数。它会将
int
成员初始化为
0
。你可以自己看到@AzzA:仅仅因为程序显示可观察的行为并不意味着它是正确的。无论如何,我编辑了答案,添加了解释其工作方式的标准规范。是的,我不介意将我的错误答案编辑为正确答案。这是正确的行为。如果需要,编译器生成的默认构造函数也将初始化
vtable
。因此,这是正确和预期的行为。@AzzA:你能提供标准中的参考吗,它说默认构造函数将初始化
v-table
?这是一个全面的语句,标准不支持注意
v-table
总之,动态调度是一个实现细节。不要依赖于可观察的行为、未定义的行为和未指定的行为,也不要基于这些行为
#include <iostream>

int main( void )
{
 int i = -123;

 i = int(); 

 std::cout << i << std::endl; 


 return( 0 );
}
0
date any =date();
              ^^^
date any;