类中未初始化变量和合成默认构造函数

事情起源于我想写个函数试一下友元的用法,结果发现没有写任何构造函数的类型直接cout他的在定义中未初始化的int报未初始化的错。
不是说没有构造函数,编译器会自己生成一个,然后按照声明次序给成员变量初始化吗?java里面不就是自动的初始化为0啊null之类的。而且c++ primer 原话是
只有当一个类没有定义构造函数时, 编译器才会自动生成一个默认构造函数。

当然后来细看这句话也没有错,只是自己想当然了。下面是正文。
--------------------------------------------分割线---------------------------------------
参考:《什么是默认构造函数?》很清楚,推荐阅读。下面是我的一些补充实验和结论搬运。

概念:初始化,默认构造函数,合成默认构造函数。
默认构造函数就是没有参数(不包括隐式的this)的构造函数,包括自己定义的没有参数的构造函数,或者自己定义的有默认参数的构造函数。

合成默认构造函数就是没有自定义构造函数时,编译器自己合成的。

初始化,我查了只有全局变量会被自动地初始化。其他的一些内置类型(int 之类)或者复合类型(int[])的不会被自动的初始化。

class X{
	int a; 
public:
	X();
	X(int s=1);//有默认参数的构造函数
}

先看结论:

注意,这两个观点是错误的:

  • 类如果没有定义任何的构造函数,那么编译器(一定会!)将为类定义一个合成的默认构造函数
  • 合成默认构造函数会初始化类中所有的数据成员。

正确的应该是

只有在编译器需要默认构造函数来完成编译任务的时候,编译器才会为没有任何构造函数的类合成一个默认构造函数,或者是把这些操作插入到已有的构造函数中去。

编译器需要默认构造函数的四种情况,总结起来就是:

a. 调用对象成员或基类的默认构造函数。
b. 为对象初始化虚表指针与虚基类指针。

详细解释请再次看参考,本文只是补充一些事例和用法。

代码示例:
情况一:
成员变量全是内置类型,且没有初始化;没有默认构造函数。
直接调用,报未初始化的错误。

如果定义里面写的是a=1,实测程序正常执行。
在这里插入图片描述
情况2:
成员有类对象,但该类被声明时候不会合成构造函数。
在这里插入图片描述
情况3:
拥有一个类对象成员,该类有默认构造函数。因为初始化Y需要调用Y 的构造函数,所以编译器需要给X一个合成默认构造函数,所以其他变量也一起按照声明顺序被初始化了,但是内置和复合类型还是没人管。
在这里插入图片描述
下面这个试验是说明全局变量会被初始化为0,而类里面的内置变量被随便分配了值
在这里插入图片描述
最后我们再来回顾c++ primer:

合成的默认构造函数( synthesized default ) 使用与变量初始化相同的规则来初始
化成员。
具有类类型的成员通过运行各自的默认构造函数来进行初始化。

内置和复合类型的成员,如指针和数组, 只对定义在全局作用域中的对象才初始化。当对象定义在局部作用域中时, 内置或复合类型的成员不进行初始化。如果类包含内置或复合类型的成员, 则该类不应该依赖于合成的默认构造函数。它应该定义自己的构造函数来初始化这些成员。

此外, 每个构造函数应该为每个内置或复合类型的成员提供初始化式。没有初始化内置或复合类型成员的构造函数, 将使那些成员处于未定义的状态。除了作为赋值的目标之外, 以任何方式使用一个未定义的成员都是错误的

如果每个构造函数将每个成员设置为明确的己知状态, 则成员函数可以区分空对象和具有实际值的对象。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值