Effective C++ 随记 第五章(实现)

条款26:尽可能延后变量定义式的出现时间

循环体内的变量定义:A)循环开始之前;B)循环内部

1)赋值成本比“构造+析构”成本低 -> 使用方式A;

2)代码对效率高度敏感 -> 使用方式A;

3)其它情况 -> 使用方式B。

 

请记住:

1):尽可能延后变量定义式的出现,可增加程序的清晰度并改善程序的效率。

 

条款27:尽量少做转型动作

 C风格类型转换: T(expression) 、(T) expression // 将 expression 类型转换为 T 类型。

 

1)const_cast 将对象的常量性转除(去除)。 唯一的此功能 C++ style转型操作符。

2)dynamic_cast 主要用于“安全向下转型” ,决定某对象是否归属继承体系中的某个类型。  唯一在旧式语法不可实现。

3)reinterpret_cast 执行低级转型,结果却决于编译器(不可移植)。  例如将 pointer-to-int 转型为 int。

4)static_cast 强迫隐式转换。 将 non-const 转换为 const。 也可以实现反向转换 ,如 void* 指针转换为 typed 指针;将 pointer-to-base 转换为 pointer-to-derived 。 但是无法将 const 转换为 non-const。

 

请记住:

1):如果可以,尽量避免转型。在注重效率的代码中避免 dynamic_cast。

2):如果转型是必要的,试着将其隐藏在某个函数中。避免可以自己进行转型。

3):尽量使用 C++ style(新式)转型,不要使用旧式转型(C style)。前者容易辨识且分类清晰。

 

条款28:避免返回 handles 指向对象内部成分

 handles(号码牌):包含reference、指针和迭代器。   使用会降低对象的封装性。

 

如果 const 成员函数传出一个 reference,其指向的数据与对象自身有关且存储于对象之外,返回的 reference 可能导致指向的数据被修改。

 

请记住:

1):避免返回 handles 指向对象内部,可以增加封装性,帮助 const 成员函数的行为像个 const,降低“虚吊号码牌”的可能性。

 

条款29:为“异常安全”而努力是值得的

请记住:

1):异常安全函数即使发生异常也不会泄露资源或允许任何数据结构破坏。这样的函数分为三种可能保证:基本型、强烈型、不抛异常型。

2):“强烈保证”往往能够以 copy-and-swap 实现出来,但“强烈保证”并非对所有函数都可实现或具有现实意义。

3):函数提供的“异常安全保证”通常最高只等于其调用各函数种“异常保证”的最弱者。

 

条款30:透彻了解 inlining 的里里外外

inline函数的观念:将inline函数的每一个调用替换为函数本体。

可能会造成程序编译生成的目标码过大;

对于短小的函数,反而可以使得目标码变小。

 

类的成员函数的 定义式 在类内,则该成员函数 隐式 成为 inline 函数。

inline函数一般置于头文件中:通常在编译过程(也存在连接、运行期)中就需要将“函数调用”替换为“函数本体”。

Template通常也置于头文件中:在编译期编译程序(也有连接期)的过程中,需要在具现化模板函数之前知道模板的形式。

Template具现化与inline函数: 如果该模板具现化出来的函数都为inline函数,才将该模板声明为inline。

 

指向inline函数的调用不一定为inline调用:例如函数指针调用。

 

inline函数无法随着程序库的升级而升级,所有使用该函数的客户必须重新编译。

大部分调试器无法调试inline函数。

 

请记住:

1)将大多数inline函数限制咋 小型、频繁调用 的函数上,可以使得调试、升级更容易,也可以最小化代码膨胀问题,最大化程序的速度提升机会;

2)不要因为 function template 出现在头文件就将其声明为inline函数。

 

 条款31:将文件间的编译依存关系降至最低

 1)如果适用 object reference 或 object pointer 可以完成任务,就不要适用 object 。

2)如果能够,尽量以 class 声明式替换 class 定义式。

3)为声明式和定义式提供不同的头文件。

 

Handle class

 

#include "datefwd.h" // 这个头文件内

//声明(但未定义)class Date

Date today();

void ClearApp(Date d);

 

Interface class  基类的函数中的成员函数全部为 vritual 函数

基类定义种加入:

class Person{

public:

static std::tr1::shared_ptr<Person> create(const std::string& name,

          const Date& birthday, const Address& addr);

};

使用:

// 创建一个对象,使用 Person 接口

std::tr1::shared_ptr<Person> pp(Person::create(name, date, address));

 

也可以继承产生一个派生类,在派生类中真正实现(覆盖)成员函数

从而实现成员函数 Person::creat()

class RealPerson:public Person{

}

 

请记住:

1):支持“编译依存最小性”的一般构想是:相依于声明式,不要相依于定义式。基于此构想的两个手段是 Handle class 和 Interface class。

2):程序库头文件应该以“完全且仅有声明式”的形式存在。这种做法不论是否涉及 template 都适用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值