博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【04】确定对象被使用之前已先被初始化
阅读量:6931 次
发布时间:2019-06-27

本文共 1207 字,大约阅读时间需要 4 分钟。

1、首先区分初始化和赋值。

  初始化:创建对象时赋给初始值。赋值:擦除对象当前值,并用新值代替。因此,区分初始化和赋值的关键是,看看对象当前是否已经有值了。

2、创建对象的时候,如果没有初始化,对象的值是什么?

  取决于对象的类型和对象定义的位置。

  a、如果对象是内置类型,定义在方法外,它的值为0,定义在方法内,没有初始化。

  b、如果对象是类类型,无论定义在哪里,都会调用默认构造方法,也就是说,对于类类型的对象,不存在没有初始化的情况。

3、现在考虑,类中的数据成员,也就是字段。类的构造方法执行两个过程:成员初始化列表和方法内赋值。对于类类型,前者用于初始化,即copy构造;后者用于赋值,即copy赋值。对于内置类型,前者和后者都可用于初始化,如果前者没有初始化,可在后者中初始化。

4、如果没有在成员初始化列表中显式初始化,出现什么情况?

  a、如果是类类型,隐式初始化,调用默认构造方法;

  b、如果是内置类型,不被初始化,它的取值,按照变量初始化规则进行。它的取值依赖于所属对象的作用域,所属对象是局部对象,不被初始化,所属对象是全局对象,初始化为0。如果内置类型是static字段呢?static字段必须在头文件之外定义(static+const+int是个特殊情况,可以只声明,不定义),定义时没有初始化,取值多少?因为它是类作用域内的全局变量,取值为0。

5、因此,对于类类型,,在方法内赋值,相当于执行了一次初始化,一次赋值。为了效率,应该在成员初始化列表中初始化。对于内置类型,两种方式等效,为了一致性,也在成员初始化列表中进行。但是,有三种情况必须在初始化列表中进行:a、类类型没有默认构造方法;b、引用;c、const对象。

6、类中字段的初始化顺序与初始化列表的顺序无关,而是与类定义中的声明顺序保持一致。

7、static对象可认为包括:全局对象,定义在namespace内的对象,在class内、方法内、以及file内的static对象。根据作用域可分为local static对象和non-local static对象,方法内的static对象时local static对象,其他的static对象是non-local static对象。

8、现在考虑,不同编译单元中non-local static对象的初始化顺序。C++中,对于不同编译单元的non-local static对象的初始化顺序没有明确定义,也就是说初始化顺序是不确定的。思考,为什么C++不定义,因为做不到。因为C++是单独分别编译,当前编译单元的编译不依赖其他编译单元的编译。

9、那怎么解决上面的问题呢?

  使用一个方法,方法内部创建一个local static对象,返回这个local static 对象。对于多线程系统,为了保证只有一个local static对象,需要使用加锁机制。

转载地址:http://bjmjl.baihongyu.com/

你可能感兴趣的文章
Oracle数据库ASM磁盘组+ASM2_ARCH使用率高
查看>>
ActiveMq-JMS简单实例使用tomcat
查看>>
医疗信息化 医学信息 医院管理 资料下载
查看>>
10G~11G体系结构图
查看>>
shell学习笔记(3)
查看>>
用一棵二叉树的前序遍历结果和中序遍历结果还原这棵二叉树——6
查看>>
KVM虚拟化笔记(二)------kvm虚拟机Linux系统安装
查看>>
6.python序列化功能之json&pickle
查看>>
路由器可以关闭的一些不必要服务
查看>>
SQL—— 事务
查看>>
OC基础第一讲
查看>>
php开启与关闭错误提示
查看>>
两个不同vim之间复制内容
查看>>
win10打不开jar文件方法
查看>>
血药谷浓度能否区分经TNF拮抗剂诱导获得缓解和低活动度的RA患者
查看>>
公式编辑器矩阵该怎么修改
查看>>
oracle 发邮件功能
查看>>
SpringBoot简介以及如何创建一个SpringBoot模块
查看>>
PHP获取不带后缀的文件名方法
查看>>
Int 2e 与 Sysenter区别
查看>>