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;