未定义构造函数的默认值

时间:2012-02-18 05:33:25

标签: c++ constructor

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;

}

每次运行程序时,此程序的输出为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是任何其他构造函数都无法接触的,并且它是值初始化,如答案中所述

3 个答案:

答案 0 :(得分:5)

您看到的行为是为您的班级定义的。


如何&amp;为什么行为定义明确?

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

根据C ++标准,可以通过3种方式初始化对象:

  • 零初始化
  • 默认初始化&amp;
  • 价值初始化

当类型名称或构造函数初始值设定项后跟()时,初始化是通过值初始化。

因此,

date any =date();
              ^^^

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

date any;

将是默认初始化

值初始化为任何构造函数不可及的成员提供初始值零 在您的计划中,nm超出了任何构造函数的范围,因此会初始化为0


回答编辑问题:
在您编辑的案例中,您的类提供了无参数构造函数date(),它能够(并且应该)初始化成员nm,但此构造函数不会初始化两个成员,所以在这种情况下,没有进行零初始化,并且对象中的未初始化成员具有 Indeterminate (任意随机)值,此外该临时对象被复制到any对象它显示节目不确定的成员值。


对于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是具有用户声明的构造函数(12.1)的类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的);
   - 如果T是没有用户声明的构造函数的非联合类类型,则T的每个非静态数据成员和基类组件都是值初始化的;
   - 如果T是数组类型,则每个元素都是值初始化的;
   - 否则,对象是零初始化

答案 1 :(得分:4)

因为诅咒的编译器会为你生成一个。

编辑:由于Als说它没有回答问题,我会详细说明。使用date any = date();时,可以调用编译器生成的默认构造函数。此构造函数为所有基类和数据成员调用默认构造函数。对于您的数据成员int,默认构造函数为int(),将值设置为0。这是code on ideone.com

#include <iostream>

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

 i = int(); 

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


 return( 0 );
}

节目输出:

0

答案 2 :(得分:0)

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

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