第五章 实现

来源:互联网 发布:金山数据恢复账号共享 编辑:程序博客网 时间:2024/06/05 19:30

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

什么是“尽量延后”的真正定义?我们不只应该延后变量的定义,直到非得使用该变量的前一刻为止,甚至应该尝试延后这份定义直到能够给他初值实参为止。如果这样,不仅能够避免构造和析构非必要的对象,还可以避免无意义的default构造行为。更深层说,以“具有明显意义的初值”将变量初值化,还可以附带说明变量的目的。

 

 

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

旧式转型:(Texpression    Texpression

C++的新式转型:

const_cast<T>(expression)

dynamic_casst<T>(expression)

reinterpret_cast<T>(expression)

static_cast<T>(expression)

作用:

const_cast:通常被用来将对象的常量性转除。他也是唯一由此功能的C++转型操作符。

dynamic_cast:主要用来执行“安全向下转型”,也就是用来决定某个对象是否归属继承图系中的某个类型。

reinterpret_cast:意图执行低级转型,实际动作和结果可能取决于编译器。

static_cast:用来强迫隐式转换,可以实现多种转换,但无法实现const转换为non-const

旧事转换依然合法,但是新式更好:(1)容易辨认(2)目标明确,编译器容易诊断。常用的旧式转换是单参数的构造函数,也可用新式转换替换,尽量始终明智的使用新式转换。

一定要非常谨慎的使用类型转换,如果打算使用,一定要提醒自己是不是将局面引到了错误的方向。

例如:

在派生类中实现基类的虚函数,以下面的方式是错误的

virtual void onresize()

{

static_cast<Window>(this*).onresize();//错误,其实Window::onreser()即可

........

}

当执行上述动作时,他是在“当前动作的基类成分”的副本上调用Window::onresize(),然后在当前对象身上执行派生类的onresiae()专属动作。!!!(基!派!分离)

 

 

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

如果一成员函数返回引用改变成员,是不良好的行为,原因

1)成员变量的封装性被改变,最多等于返回其引用的函数的访问级别。

2)如果const的成员变量传出一个引用,那么这个成员变量有改动的风险。

 

引用,指针和迭代器统统都是所谓的handles(号码牌,用来取得某个对象),而返回”对象内部数据“的handle,随时而来的便是“降低对象封装”的风险。通常我们认为,对象的“内部”就是指它的成员变量,但其实不被公开使用的成员函数(protected或者private)也是内部成员的一部分。因此也应该留心不要返回他们的handles。这意味着你绝对不应该令成员函数返回一个指针指向“访问级别较低”的成员函数。

还有一个危险:有一个handle被传递出去,但是“handle比其所指的对象寿命更长”!!!

 

 

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

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

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

 

 

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

inline函数的整体观念是,将对函数的调用都已函数本体替换。

inline只是对编译器的一个申请,不是强制命令。

定义在类内的函数都是隐式inline(若friend也被定义在类内也是inline)。

有时内联的函数并不是表面那么简单。

 

 

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

以“声明的依存性”替换“定义的依存性”:实现中让头文件尽量自我满足,万一做不到,则让他与其他文件内的声明式相依。

例如在一个类内用到其他类的对象:(1)如果使用对象的引用或指针可以完成任务,就不要使用对象(2)如果能够,尽量以class声明式替换class定义式。

 

在程序发展过程中使用Handle classinterface class以求实现代码对客户的冲击最小。而当他们导致速度和或大小差异过于过于重大以至于class之间的耦合相形之下不成为关键时,就以具象类替换handle class interface class



0 0