Effective C++ (05)
来源:互联网 发布:大数据时代 书 编辑:程序博客网 时间:2024/05/16 14:22
条款28:避免返回handles指向对象内部成分
可能悬空,hanndle指向的东西不再存在
但也有例外:operator[]
避免返回handle:指针、引用、迭代器指向对象内部
条款29:为异常安全努力
异常安全:
不泄露任何资源:
不允许败坏数据
代码越短,出错机会越少
异常安全的函数有以下保证:
基本保证:如果抛出异常,程序内的任何事物仍然保持在有效状态下
强烈保证:如果函数成功,是完全成功;如果函数失败,程序会回复到调用前的状态
不抛异常:承诺绝不抛出异常
异常安全代码满足上述三者之一
copy and swap原则:
为打算修改的对象作出一份副本,在副本上做修改,若修改抛出异常,则原件不变;如果修改成功,将原件和副本做交换
条款30:了解inline
免除函数调用的成本
对函数的每一个调用都用函数本体代替
inline函数:
工作在编译器层,编译器负责做参数检查,返回值类型转换,这是预处理器做不了的。
对于任何函数,编译器都会把函数声明放入符号表,而inline函数,同时将函数体(源码或汇编取决于编译器)放入符号表。当调用时,做必要的检查,然后插入代码,对于类成员函数,还会插入this指针。
inline的使用
在类中,如果声明和定义写在一起,则是inline函数
在类外如果定义inline函数,必须声明和定义写在一起
例如,inline void Func(); 然后再别处实现,则没有inline的效果
一般将inline函数定义在头文件中,多个文件包含不会出现重定义(内部链接,保存在符号表里)
inline函数的缺点
和宏一样,其不能调试,inline函数没有地址
inline只是对编译器的一种暗示,编译器有最终inline与否的权利
当有循环时,一般不inline;
当函数体超复杂或较大时,一般不inline;
当函数内递归调用时,绝对不inline;
当须取函数指针时,绝对不inline;
可能引起代码膨胀
将inline函数限制在小型、被频繁调用的函数上
条款31:将文件间的编译依存关系降至最低
将接口从实现中分离
如果使用对象指针或引用能完成任务,就不要使用对象
尽量以class声明替换class定义
条款32:确定public继承关系是is-a关系
公开继承意味着is-a的关系
public继承:适用于base class身上的每一件事必须完全适用于子类
鸟会飞,而企鹅不会,因此不能直接继承于bird
条款33:继承体系下的名称掩盖
当编译器看到某个name(func 或者 data)时,查找各个作用于,看是否存在name,先从local找,再从base class找
Class Base{Private:Int x;Public:Virtual void mf1() = 0;Virtual void mf1(int);Virtual void mf2();Void mf3();Void mf3(double);};
Class Derived : public Base{Public:Virtual void mf1();Void mf3();Void mf4();};
基类中所有的fm1和mf3都被子类掩盖了!
只要重载了一个fm1,base中所有的fm1都被覆盖
Base::mf1()和Base::mf3()不再被继承
Derived d;int x;d.mf1(); OK 调用Derived::mf1d.mf1(x); Error!基类中的被掩盖d.mf2(); OK 调用Base::mf2d.mf3(); OK调用Base::mf3d.mf3(x); Error,被掩盖
掩盖时,只管名字,而不论其类型
例如:
int func(){ doublex; { intx; // 这个x会掩盖外围的double x,如果 }}
可以使用using声明使父类的可见
Class Base{Private:Int x;Public:Virtual void mf1() = 0;Virtual void mf1(int);Virtual void mf2();Void mf3();Void mf3(double);};
Class Derived : public Base{Public:Using Base::mf1;// 让base中所有名weiUsing Base::mf3;// mf1 mf3的可见Virtual void mf1();Void mf3();Void mf4();};
Derived d;int x;d.mf1(); OK 调用Derived::mf1d.mf1(x); OK! 调用基类的!d.mf2(); OK 调用Base::mf2d.mf3(); OK 调用Derived::mf3d.mf3(x); OK 调用Base::mf3
如果继承base并加上重载,而又想使用base内的func,需要using::
在public继承体系下,必须继承所有的方法!
对于private继承:转向函数
Class Base{Private:Int x;Public:Virtual void mf1() = 0;Virtual void mf1(int);};
Class Derived : private Base{Public:Virtual void mf1(){ Base::mf1();} // 这里为何可见???};
Derived d;int x;d.mf1(); OK 调用Derived::mf1,然后转向调用base的函数d.mf1(x); Error,Base中的被掩盖
可以使用using或转向函数
- Effective C++:条款05
- 《Effective C++》条款05
- Effective C++(四)
- Effective C++(五)
- 《Effective C++》(一)
- 《Effective C++》(二)
- 《Effective C++》(三)
- 《Effective C++》(四)
- 《Effective C++》(五)
- 《Effective C++》(六)
- 《Effective C++》笔记(一)
- 《Effective C++》笔记(一)
- Effective C++(中文版)下载
- Effective C++(三)资源管理
- Effective C++(五)实现
- 《Effective C++》读书笔记(二)
- 《Effective C++》读书笔记(三)
- 《Effective C++》读书笔记(四)
- Android应用程序已经安装,当点击时提示该软件没有安装
- Effective C++ (04)
- WINDOWS SERVER 2008开启桌面主题
- ArrayList源码分析
- 基于实用主义的Scrum
- Effective C++ (05)
- Win7下IE8无法打开https类型的网站解决方法笔记
- php curl_multi demo 例子
- hdu 2674 N!Again
- WebStrom 自带console调试js:NETWORK_ERR: XMLHttpRequest Exception 101
- Windows下用fastboot烧写Android4.0.4系统镜像
- 47道 oracle SQL测试题
- 第十三周训练 problem d
- acm 2034