条款4:确定对象在使用前已被初始化
考虑如下设计:
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:确定对象在使用前已被初始化相关推荐
- C++确定对象被使用前已先被初始化
确定对象被使用前已先被初始化 读取未初始化对象的后果 按对象的类型划分 按对象的作用域与生命周期划分 读取未初始化对象的后果 读取未被初始化的值会导致不明确的行为.在某些平台上,仅仅只是读取未初始化的 ...
- 确定对象在使用前已经被初始化
int nUserID; //这样的代码在VC6的DEBUG版本是初始化为0,RELEASE是未定义的数值. //之后有验证的VS10之后的版本DEBUG版本都是未定义的值. std::cout &l ...
- 中国疾控中心回应论文争议:所有病例在论文撰写前已向社会公布
本文综合自人民网.科技部.知识分子.知乎网友Leorance 刚刚,国内多家权威媒体报道了中国疾病预防控制中心的官方回应. 内容如下-- 2020年1月29日,中国疾病预防控制中心.湖北省疾病预防控制 ...
- 特斯拉前员工承认备份AutoPilot代码,但入职小鹏汽车前已删除
允中 发自 凹非寺 量子位 报道 | 公众号 QbitAI 特斯拉状告前华人员工一案,现在有了最新进展: 双方提交的法庭文件曝光了. 前特斯拉高级工程师曹光植(后入职小鹏汽车任感知主管)承认,在20 ...
- 四川地震发生前已有征兆?网民问责地震局未预警
地震发生之后,"地震能否准确预报"迅速在网上引发极大争论,有的网民问罪地震局为什么没有提前预报,甚至比网友的反应速度还慢.但是,也有网友表示地震根本不能预报,但可以预警. 最先报地 ...
- js 对象数组中的已知对象的属性得到对象下标
arr 对象数组, wyw已知属性 多用于接口返回数据后根据已知属性查其他属性 var arr = new Array({"name": "wxx", &quo ...
- {code:-1,error:`QcloudSecretId`不能为空,请确保 SDK 配置已正确初始化}解决方法
微信小程序开发交流qq群 173683895 承接微信小程序开发.扫码加微信. 微信小程序云开发登录报错: {"code":-1,"error":&q ...
- C++中变量使用前一定要初始化
在C++中变量声明后,在使用前一定要初始化. 1>如下代码: #include<iostream> using namespace std; int main(){for(int i ...
- Springboot项目启动前执行数据库初始化脚本
背景:项目里面遇到了要在springboot项目启动前做数据库初始化的需求.总结一下几种方案: 1.使用flywaydb,启动工程的时候同时初始化脚本.集成倒是不难,主要是要解决bean的顺序加载问题 ...
最新文章
- VLAN系列二: 实现VLAN的机制
- WinJS实用开发技巧(2):使用artTemplate打造对话列表
- java 中文 图片_java之服务器端写图片中文乱码
- python地图 两点距离_没学过还真不会!怎样才能画出准确的地图?
- 玩冒险岛java卸载_如何删除冒险岛安装了,现在不想玩
- VOS防止盗打及后门的安全策略
- Matlab-杆单元整体刚度矩阵组装(有限元基础-曾攀)
- NBNS 数据包 和 NetBIOS 协议
- 简易cad导出pdf程序源码
- Python模块selenium实例:电影分类排名数据生成json,sqlite和excel(openpyxl)文件(二)
- 看了那些Google大神Jeff Dean的传说后,我跪了!
- matlab中的subplot函数
- win10家庭版调出组策略_正版Win10免费送!这绝对是全网最低价的正版Win10系统
- 做一个优秀的开源项目,需要注意哪些方面?
- AlexNet论文阅读总结及代码
- 大航海日志--do rome as romans do
- 判断图有无环_21考研有机化学打卡第四题——芳香性判断
- OLAP有哪些实现方法?
- linux下CUPS学习心得
- mysql多实例的安装和管理(一台服务器上运行两个mysql实例)