更高效的C++_More Effective CPP手记一之基础议题
来源:互联网 发布:北京精雕如何编程 编辑:程序博客网 时间:2024/06/14 23:56
基础议题
M1.指针与引用类型的选用
1.任何时候都不能使用只想控制的引用,引用一经定义,必须指向某个对象,之后不能改变。
2.如果设计中变量不能为空,应该使用引用,而且在使用时不需要对变量进行验证其合法性,效率要比指针要高。
3.指针与引用的一个重要区别是:指针可以指向NULL,而且可以重新指向另一个不同的对象,而引用初始化时被指定对象,之后不能改变。
4.当你重载某些操作符的时候,例如operator[],为防止不必要的误解时,应该选择引用。
5.总的来说,如果总是指向一个对象并且不改变指向,应该使用引用,否则在以下情况使用指针。
1)存在不指向对象的可能。
2)能够在不同时刻指向不同对象。
M2.使用C++风格的类型传唤
1.C风格转换缺点:
1)过于粗鲁,什么类型都能转换。
2)在程序语句中难以识别。
2.一般类似于C风格的转换,应用static_cast<type>(expression)替换。
(type) expression ---->static_cast<type>(expression)
3.转换掉对象的const属性或volatileness属性,使用const_cast<type>(expression)
const Person p1;
Person& p2 = const_cast<Person>(p1);
4.dynamic_cast<type>(expression)可以将指向基类的指针或引用转换成派生类的指针或引用,前提是要有虚函数存在,此类只能用于继承关系的转换,转换失败将返回空指针或抛出异常。
5.函数指针转换,reinterpret_cast<type>(expression),其转换结果都是执行期定义,代码很难移植。
例:
typedef void (*FuncPtr)();
int doSomething();
FuncPtr func = &doSomething();//错误,类型不匹配!
FuncPtr func = reinterpret_cast<FuncPtr> &doSomething;//reinterpret转换可以迫使编译器以你的方法去看待他们
6.新的类型转换符不美观,但是这样程序更容易进行解析,他们云溪编译器检测出来原来不能发现的错误。
M3.不要对数组使用多态
1.例子:
class BST{};
class BalancedBST:public BST{};
有这样一个函数,打印出每一个BST对象的内容
void printBSTArray(ostream& s,const BST arrays[],int numElements)
{
for(int i = 0; i<numElements;++i)
s<<array[i];//假设BST类重载了操作符<<
}
当传入一个BST数组,可以正常运行,而传入一个BalancedBST类型,结果未定义,原理如下:
array[i]相当于*(array),而array十指相扣BST数组的首地址,数组中每个对象的大小是sizeof(BST),所以数组中个元素与array起始地址的间隔是i*sizeof(BST);
当你把BalancedBST对象数组传入到函数,编译器还是会认为数组中对象与起始地址的间隔是i*sizeof(BST),而此时每个对象的大小是sizeof(BalancedBST)。
2.自己理解:不要将参数设置为含有多态性的对象,改用指针或者引用。原因有二:
1)将多态性质的对象传入函数,会导致变量的拷贝,从而产生临时对象,降低性能。
2)将对象作为参数,会发生object slicing,并不会体现多态性质,只有引用和指针才会发生多态类型识别。
M4.避免无用的缺省构造函数
1.缺省的构造函数,可以在什么都不提供的情况下产生对象,有时候这种对象是无意义的。
2.提供无意义的缺省构造函数会影响类的工作效率,成员函数必须花费更多的时间,来进行测试对象的数据成员是否被正确初始化。
3.不使用缺省构造同样会带来不便
1)定义数组时,动态初始化问题。解决办法如下:
首先使用operator new[]为数组分配raw memory,避免浪费内存,
void* rawMemory = operator new[](10*sizeof(EquipmentPiece));
EquipmentPiece* bestPieces = static_cast<EquipmentPiece*>(rawMemory);
其次使用placement new进行函数构造
for(int i = 0;i<10;++i)
{
new (&bestPieces[i]) EquipmentPiece(ID)
}
注意:使用placement new构造的对象,需要使用opeator delete[](rawMemory);直接删除一个不使用new分配的内存指针,结果未定义。
2)无法再许多类模板中使用,此时对模板的定义也不能依赖于默认构造函数。
3)继承层次中,派生类很难与不提供默认构造函数的虚基类进行合作。
- 更高效的C++_More Effective CPP手记一之基础议题
- More Effective(一)基础议题
- 《More Effective C++》重点摘要一:基础议题
- 《More Effective C++》读书笔记-基础议题
- <<More Effective C++>>读书笔记1: 基础议题
- more effective c++基础议题
- More Effective C++读书笔记---基础议题
- More Effective C++ 第一部分 基础议题
- More Effective C++ 读书摘要(一、基础议题 二、运算符)Item1 - 8
- more effective c++使用条款(一)—— 基础议题/运算符
- 《Effective C++》读书笔记之const高效使用
- More Effective C++总结(1):基础议题
- 【more effective c++读书笔记】【第1章】基础议题(1)
- 【more effective c++读书笔记】【第1章】基础议题(2)
- More Effective C++学习笔记(1)-基础议题
- More Effective C++议题【一】:指针和引用
- 基础议题
- 高效effective C++ 55条款之个人学习笔记一
- 孙鑫VC++深入详解(3):简单绘图
- 控件拖动后,某些事件引起的布局重置或位置还原问题
- 用C++实现七种排序算法,可选择排序方法,简单易懂。
- javascript面向对象 属性和方法
- git介绍
- 更高效的C++_More Effective CPP手记一之基础议题
- linux下的通配符与正则表达式
- Python中的input和raw_input
- GVim常用配置
- PAT (Advanced) 1061. Dating (20)
- 代码块、构造方法在对象的初始化顺序
- V4L2编程初体验
- IE的layout属性详解
- 第一周项目1 用枚举表示对称方式