深度探索C++对象模型之第二章:构造函数语意学之成员初始值列表
当我们需要设置class member的初值时,要么是经过member initialization list ,要么在construcotr内。
一、先讨论必须使用member initialization list的四种情况:
在以下四种情况,为了能够让程序被顺利编译,必须使用member initialization list:
- 当初始化一个reference mmember时
- 当初始化一个const member时
- 当调用一个base class的constructor时,并且基类有一组参数
- 当调用一个member class的constructor时,并且成员类也有一组参数
虽然在四种情况下,使用构造函数初始化成员,程序可以被正确编译并执行,但是效率不高,举例如下:
class Word{
String _name;
int _cnt;
public:
//此时是在构造函数内执行数据成员的初始化
Word() { _name = ; _cnt = ;}
};
上例对应四种情况的第四种,在这里Word constructor会先产生一个临时String object,然后将它初始化,之后以一个赋值运算符将临时性object指定给_name,然后再将那个临时String object摧毁(析构)。以下是编译器对Word constructor扩张的结果:
//C++伪代码
Word::Word()
{
//调用Stringd的default constructor
_name.String::String(); //产生临时对象
String temp = String(); //memberwise的拷贝_name
_name.String::operator = (temp); //摧毁临时对象 temp
temp.String::~String(); _cnt = ; }
如果在成员初始值列表中进行成员初始化操作,明显更有效率,即如下所示:
Word::Word: _name(){
_cnt = ;
}
//将会被扩展成下面形式:
Word::Word()
{
//调用String(int)构造函数
_name.String::String();
_cnt = ;
}
二、讨论下成员初始值列表中初始化的顺序:
举个例子:
Word::Word()
: _cnt(),_name() { }
对于上述构造函数,编译器会一一执行初始值列表,以适当顺序(这个顺序是由class中member的声明顺序决定的,而不是initialization list的顺序决定的)在构造函数内安插初始化操作。编译器在constructor的扩展如下:
Word::Word ()
{
_name.String::String();
_cnt = ;
}
由初始化顺序可能会导致一个意想不到的错误:如下所示:
class X{
int i;
int j;
public:
X(int val)
:j(val),i(j) {}
};
在上述代码中,初始化的顺序应该是先初始i,因为i声明在前,但是因为j一开始没有初值,所以i(j)的结果会导致i无法预知其值。
所以我们可以将i的初始化操作放在构造函数内部,此时initialization list的执行顺序一定在explicit user code之前。如下所示:
X::X(int val)
: j(val) { i = j;}
三、再来讨论其他两个关于初始化位置的问题:
其一是、当调用一个成员函数来初始化一个成员的值时,但是请使用构造函数内的member,而不是member initialization list中的member,如下所示:
X::X(int val)
: i(xfoo(val)),j(val) {}
此时和此object相关的this指针,已经被构建妥当,编译器将constructor扩张为如下形式:
X::X ()
{
i = this->xfoo(val);
j = val;
}
另一情况是还是不要使用派生类的成员函数作为基类构造函数的参数了。不太好
深度探索C++对象模型之第二章:构造函数语意学之成员初始值列表的更多相关文章
- 《深度探索C++对象模型》第二章 | 构造函数语意学
默认构造函数的构建操作 默认构造函数在需要的时候被编译器合成出来.这里"在需要的时候"指的是编译器需要的时候. 带有默认构造函数的成员对象 如果一个类没有任何构造函数,但是它包含一 ...
- 深度探索C++对象模型之第二章:构造函数语意学之Copy constructor的构造操作
C++ Standard将copy constructor分为trivial 和nontrivial两种:只有nontrivial的实例才会被合成于程序之中.决定一个copy constructor是 ...
- 深度探索C++对象模型之第二章:构造函数语意学之Default constructor的构造操作
C++新手一般由两个常见的误解: 如果任何class没有定义默认构造函数(default constructor),编译器就会合成一个来. 编译器合成的的default constructor会显示的 ...
- 【C++对象模型】第二章 构造函数语意学
1.Default Constructor 当编译器需要的时候,default constructor会被合成出来,只执行编译器所需要的任务(将members适当初始化). 1.1 带有 Defau ...
- 深度探索C++对象模型之第一章:关于对象之C++对象模型
一.C和C++对比: C语言的Point3d: 数据成员定义在结构体之内,存在一组各个以功能为导向的函数中,共同处理外部的数据. typedef struct point3d { float x; f ...
- 深度探索C++对象模型之第一章:关于对象之对象的差异
一.三种程序设计范式: C++程序设计模型支持三种程序设计范式(programming paradiams). 程序模型(procedural model) char boy[] = "cc ...
- 《深度探索C++对象模型》第一章 | 关于对象
C++对象模式 非静态数据成员放置在每个类对象内,静态数据成员则被放置在所有类对象之外.静态和非静态的成员函数也被放置在所有类对象之外.每个类产生一堆指向虚函数的指针,放在虚表(vtbl)中.每个类对 ...
- 深度探索C++对象模型第四章:函数语义学
C++有三种类型的成员函数:static/nonstatic/virtual 一.成员的各种调用方式 C with class 只支持非静态成员函数(Nonstatic member function ...
- 深度探索C++对象模型之第一章:关于对象之关键词所引起的差异
————如果不是为了努力维护与C之间的兼容性,C++远比现在简单的多. 如果一个程序员渴望学习C++,但是他却发现书中没有熟悉的struct,一定会苦恼,将这个主题包含到C++里,可以提供语言转移时的 ...
随机推荐
- swiper 窗口宽度变化,页面宽度高度变化 导致自动滑动 解决方案
又又又又是swiper问题 背景: pc端项目,rem布局,swiper作为步骤条(上一步,下一步)的功能. 发现在屏幕拖动,宽高的变化,窗口大小的变化 会引起swiper自动滑动(到下一步). 在下 ...
- python中的模块以及包导入
python中的导入关键字:import 以及from import 1.import import一般用于导入包以及模块. 不过有个小问题: (1)当导入的是模块的时候是可以直接可以使用模块内的函 ...
- keepAlived主备及双主
nginx用默认配置即可 1.主备配置 1.主keepAlived配置 vrrp_instance VI_1 { state MASTER #主备区分 interface eth0 virtual_r ...
- python 2 学习历程(一)
在用户输入字符串的时候,有时会带有一些其他的字符,例如常见的空格 除非在网页或者某个位置声明了空格也算字符,或者一些账号等安全程度较高的环节,多了一个空格很少有人会注意到,并且愿意即时改正它们,那么这 ...
- Job 和 Cronjob 的使用
Job负责处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束.而CronJob则就是在Job上加上了时间调度. Job 我们用Job这个资源对象来创建一个任务,我们定一个Job来 ...
- canvas 压缩图片上传
问题:前端开发过程中难免会将数据提交到后台,但若是提交的数据过大,特别上传图片这类需求,如果不对上传的图片进行压缩处理,就难免会出现请求时间过长的情况,对于用户体验肯定就不是太友好,那么这时候该如何将 ...
- jq-demo-在列表中添加新节点,点击删除
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- jQuery实现全选与全部选
为了便于用户理解,直接粘贴下面的代码即可 <!DOCTYPE html> <html lang="en"> <head> <meta ch ...
- Linux(二)高级文本处理
一.cut (cut 命令可以从一个文本文件或者文本流中提取文本列 ) 1.cut语法 cut -d '分隔字符' -f fields 用于有特定分隔字符 cut -c 字符区间 ...
- 仿淘宝使用flex布局实现页面顶部和底部的固定布局
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...