考虑如下设计:

 1 #include<iostream>
 2
 3 using namespace std;
 4
 5 class Entry
 6 {
 7 public:
 8     Entry(const string& name, const string& address, const string& phone);
 9
10 private:
11     string name;
12     string address;
13     string phone;
14     int nums;
15 };
16 Entry::Entry(const string& name, const string& address, const string& phone)
17 {
18     this->name = name;            // 构造函数内的这些语句都是赋值而不是初始化
19     this->address = address;
20     this->phone = phone;
21     this->nums = 0;
22 }
23
24 int main()
25 {
26     Entry entry("name: benxintuzi", "address: 123", "phones: 123456");
27
28     return 0;
29 }

如上所述,在构造函数体内都为赋值语句,而不是初始化语句。C++规定,对象的成员变量的初始化时机发生在进入构造函数之前,这点非常重要。而对于基本变量类型如nums却不能保证进入构造函数之前将其初始化。上述语句的执行是:首先调用name/address/phone的default构造函数,然后在Entry的构造函数中对其进行赋值,如此一来,调用变量的默认构造函数就变得没有什么意义了,反正最终获得的值都会马上被换掉了。为了避免重复性的工作,利用变量的构造函数总会被调用的原则,将上述Entry的构造函数改进如下:

Entry::Entry(const string& name, const string& address, const string& phone) :

name(name), address(address), phone(phone), nums(0)

{ }

利用构造函数的初始化列表,虽然结果是相同的,但是效率会提高很多:因为初始化列表只会调用name等变量的copy构造函数,而不会再次调用Entry的赋值操作符函数了,这样Entry的构造函数体就可以做一些更有意义的事了。同样不指定实参的初始化列表同样有用,比如设计一个Entry的无参构造函数如下:

Entry::Entry() :

name(), address(), phone(), nums(0)

{ }

注意:

对于基本内置类型而言,在构造函数体内赋值与调用初始化列表指定初值,其代价是等同的。但是如果成员变量是const或者references,那么就没办法使用赋值操作了,必须使用初始化列表才能通过编译。所以我们要遵循的规则就是:总是使用初始化列表,这样做最差情况下是等效的,而一般情况下是高效的,甚至有时还是必须的。

C++类的成员初始化次序问题:

  • 先基类后派生类。
  • 类中成员变量的初始化次序依赖与声明次序,与初始化列表排列次序无关。
  • 对于不同编译单元中(一个编译单元就是指能够产生单一目标文件的那些源码:包括源码文件、头文件展开、宏展开等构成的一个大文件)的变量引用问题,为了防止引用了一个还没有被初始化的变量(比如说某些资源句柄之类的),最好的办法就是将被引用的变量通过单例模式创建出来,这样就可以保证正确的初始化顺序了

转载于:https://www.cnblogs.com/benxintuzi/p/4535556.html

条款4:确定对象在使用前已被初始化相关推荐

  1. C++确定对象被使用前已先被初始化

    确定对象被使用前已先被初始化 读取未初始化对象的后果 按对象的类型划分 按对象的作用域与生命周期划分 读取未初始化对象的后果 读取未被初始化的值会导致不明确的行为.在某些平台上,仅仅只是读取未初始化的 ...

  2. 确定对象在使用前已经被初始化

    int nUserID; //这样的代码在VC6的DEBUG版本是初始化为0,RELEASE是未定义的数值. //之后有验证的VS10之后的版本DEBUG版本都是未定义的值. std::cout &l ...

  3. 中国疾控中心回应论文争议:所有病例在论文撰写前已向社会公布

    本文综合自人民网.科技部.知识分子.知乎网友Leorance 刚刚,国内多家权威媒体报道了中国疾病预防控制中心的官方回应. 内容如下-- 2020年1月29日,中国疾病预防控制中心.湖北省疾病预防控制 ...

  4. 特斯拉前员工承认备份AutoPilot代码,但入职小鹏汽车前已删除

    允中 发自 凹非寺  量子位 报道 | 公众号 QbitAI 特斯拉状告前华人员工一案,现在有了最新进展: 双方提交的法庭文件曝光了. 前特斯拉高级工程师曹光植(后入职小鹏汽车任感知主管)承认,在20 ...

  5. 四川地震发生前已有征兆?网民问责地震局未预警

    地震发生之后,"地震能否准确预报"迅速在网上引发极大争论,有的网民问罪地震局为什么没有提前预报,甚至比网友的反应速度还慢.但是,也有网友表示地震根本不能预报,但可以预警. 最先报地 ...

  6. js 对象数组中的已知对象的属性得到对象下标

    arr 对象数组, wyw已知属性 多用于接口返回数据后根据已知属性查其他属性 var arr = new Array({"name": "wxx", &quo ...

  7. {code:-1,error:`QcloudSecretId`不能为空,请确保 SDK 配置已正确初始化}解决方法

    微信小程序开发交流qq群   173683895    承接微信小程序开发.扫码加微信. 微信小程序云开发登录报错: {"code":-1,"error":&q ...

  8. C++中变量使用前一定要初始化

    在C++中变量声明后,在使用前一定要初始化. 1>如下代码: #include<iostream> using namespace std; int main(){for(int i ...

  9. Springboot项目启动前执行数据库初始化脚本

    背景:项目里面遇到了要在springboot项目启动前做数据库初始化的需求.总结一下几种方案: 1.使用flywaydb,启动工程的时候同时初始化脚本.集成倒是不难,主要是要解决bean的顺序加载问题 ...

最新文章

  1. VLAN系列二: 实现VLAN的机制
  2. WinJS实用开发技巧(2):使用artTemplate打造对话列表
  3. java 中文 图片_java之服务器端写图片中文乱码
  4. python地图 两点距离_没学过还真不会!怎样才能画出准确的地图?
  5. 玩冒险岛java卸载_如何删除冒险岛安装了,现在不想玩
  6. VOS防止盗打及后门的安全策略
  7. Matlab-杆单元整体刚度矩阵组装(有限元基础-曾攀)
  8. NBNS 数据包 和 NetBIOS 协议
  9. 简易cad导出pdf程序源码
  10. Python模块selenium实例:电影分类排名数据生成json,sqlite和excel(openpyxl)文件(二)
  11. 看了那些Google大神Jeff Dean的传说后,我跪了!
  12. matlab中的subplot函数
  13. win10家庭版调出组策略_正版Win10免费送!这绝对是全网最低价的正版Win10系统
  14. 做一个优秀的开源项目,需要注意哪些方面?
  15. AlexNet论文阅读总结及代码
  16. 大航海日志--do rome as romans do
  17. 判断图有无环_21考研有机化学打卡第四题——芳香性判断
  18. OLAP有哪些实现方法?
  19. linux下CUPS学习心得
  20. mysql多实例的安装和管理(一台服务器上运行两个mysql实例)

热门文章

  1. exchange 2010申请分配证书服务提示:证书无效,不可用于exchange server
  2. [uboot]在uboot里面添加环境变量使用run来执行
  3. Spark Streaming中流式计算的困境与解决之道
  4. 杭电OJ1002大数据相加
  5. 【SICP归纳】6 副作用与环境模型
  6. 10大最重要的Web安全风险之三----A3,错误的认证和会话管理
  7. CodeIgniter笔记3
  8. Netty 从源码的角度深入剖析 ByteBuffer
  9. php heredoc 用法
  10. java 画笔跟swing组件_「软帝学院」:2019思维最清晰的java学习路线