effective c++ 条款 04 (对象初始化)整理
来源:互联网 发布:淘宝 电脑版 编辑:程序博客网 时间:2024/05/23 00:06
确定对象使用前已被初始化
原则:不论是类的成员变量还是其他作用域的变量,使用前都要保证已被初始化(或者说赋值)
一、无任何成员的内置类型初始化
/*内置类型通过复制完成初始化*/int x = 0;const char* a = "abc";int a[2] = {0,0};
二、STL容器初始化
STL容器关注容器大小,防止越界,初始化的工作不用关心
三、类成员变量初始化
参考:http://www.cnblogs.com/BlueTzar/articles/1223169.html
class CExample {public: int a; float b; //构造函数初始化列表 CExample(): a(0),b(8.8) {} //构造函数内部赋值 CExample() { a=0; b=8.8; }};上面的例子中两个构造函数的结果是一样的。上面的构造函数(使用初始化列表的构造函数)显式的初始化类的成员;而没使用初始化列表的构造函数是对类的成员赋值,并没有进行显式的初始化。
初始化和赋值对内置类型的成员没有什么大的区别,像上面的任一个构造函数都可以。对非内置类型成员变量,为了避免两次构造,推荐使用类构造函数初始化列表。但有的时候必须用带有初始化列表的构造函数:
1.成员类型是没有默认构造函数的类。若没有提供显示初始化式,则编译器隐式使用成员类型的默认构造函数,若类没有默认构造函数,则编译器尝试使用默认构造函数将会失败。
2.const成员或引用类型的成员。因为const对象或引用类型只能初始化,不能对他们赋值。
初始化数据成员与对数据成员赋值的含义是什么?有什么区别?
首先把数据成员按类型分类并分情况说明:
1.内置数据类型,复合类型(指针,引用)
在成员初始化列表和构造函数体内进行,在性能和结果上都是一样的
2.用户定义类型(类类型)
结果上相同,但是性能上存在很大的差别。因为类类型的数据成员对象在进入函数体前已经构造完成,也就是说在成员初始化列表处进行构造对象的工作,调用构造函数,在进入函数体之后,进行的是对已经构造好的类对象的赋值,又调用个拷贝赋值操作符才能完成(如果并未提供,则使用编译器提供的默认按成员赋值行为)
Note:
初始化列表的成员初始化顺序:
C++初始化类成员时,是按照声明的顺序初始化的,而不是按照出现在初始化列表中的顺序。
#include <iostream>using namespace std;class baseA{public: baseA() { cout << "BaseA class. " << endl; }};class baseB{public: baseB() { cout << "BaseB class. " << endl; }};class derivedA:public baseB, virtual public baseA{public: derivedA() { cout << "DerivedA class. " << endl; }};class derivedB:public baseB, virtual public baseA{public: derivedB() { cout << "DerivedB class. " << endl; }};class Derived:public derivedA, virtual public derivedB{public: Derived() { cout << "Derived class. " << endl; }};int main(){ Derived obj; cout << endl;}
重复继承(repeated inheritance):一个派生类多次继承同一个基类.
但C++并不允许一个派生类直接继承同一个基类两次或以上.
重复继承的两个种类:复制继承和共享继承
重复继承中的共享继承:通过使用虚基类,使重复基类在派生对象实例中只存储一个副本.
涉及到共享继承的派生类对象的初始化次序规则
① 最先调用虚基类的构造函数.
② 其次调用普通基类的构造函数,多个基类则按派生类声明时列出的次序从左到右.
③ 再次调用对象成员的构造函数,按类声明中对象成员出现的次序调用.
④ 最后执行派生类的构造函数.
分析:各类的类层次结构关系为
①Derived从derivedA和虚基类derivedB共同派生而来
②derivedA从baseB和虚基类baseA派生而来, derivedB从baseB和虚基类baseA派生而来
执行顺序(构造函数)
由第①层关系,根据规则可得顺序为derivedB,derivedA,Derived.
然后,对于derivedB,同样根据规则更深入分析得到的顺序是baseA,baseB,derivedB.
对于derivedA,值得注意的是derivedA和derivedB都经过虚基类baseA的派生,所以根据只存储一个副本的处理方法,
由于baseA在derivedB中已经被初始化过,derivedA中将不必再进行初始化,所以执行的将是baseB, derivedA.
最后就是Derived了.
综合可得对应构造函数顺序: baseA(), baseB(), derivedB(); baseB(), derivedA(); Derived();
- effective c++ 条款 04 (对象初始化)整理
- Effective C++:条款04:确定对象被使用前已先被初始化
- [Effective C++]条款04 确定对象被使用前已先被初始化
- 《Effective C++》学习笔记条款04 确定对象被使用前被初始化
- 读书笔记《Effective C++》条款04:确定对象被使用前已先被初始化
- 【Effective C++ 读书笔记】条款04:确定对象使用前已先被初始化
- Effective C++:条款04
- effective c++(04)之对象使用前初始化
- Effective C++——》条款4:确定对象使用前已先被初始化 .
- 《Effective C++》条款04总结
- [effictive c++] 条款04 确定对象被使用前已被初始化
- Effective C++学习4 条款04:确定对象在被使用前以被初始化
- Effective c++ 学习笔记——条款04:确定对象被使用前已先被初始化
- Effective c++ 学习笔记——条款04:确定对象被使用前已先被初始化
- Effective C++条款04解读:确定对象被使用之前已先被初始化
- 《Effective C++读书笔记》--条款04:确定对象被使用前已先被初始化
- effective c++条款4(确定对象被使用前先被初始化)
- Effective C++条款4:确定对象使用前已被初始化
- Bonobo Git Server搭建本地Git服务器(Windows 下)
- powerbuilder9学习笔记
- Linux 有问必答:如何在wget中禁用HTTP转发
- session放置在服务器内存中,不随页面传递,避免参数过多传递。
- 红黑树的研究
- effective c++ 条款 04 (对象初始化)整理
- Android Studio问题汇总
- 《数据结构》实验五【顺序树】
- 哈希索引
- C语言中负数怎么表示的?
- node-webkit html5构造可执行程序
- HDU 3183 A Magic Lamp
- 正则表达式
- HDU 1885 BFS+状态压缩