学过基本程序课的同学都知道,inline是内联的关键字,它可以建议编译器将函数的每一个调用都用函数本体替换.这是一种以空间换时间的做法.把每一次调用都用本体替换,无疑会使代码膨胀,但可以节省函数调用的成本,因为函数调用需要将之前的参数以堆栈的形式保存起来,调用结束后又要从堆栈中恢复那些参数. 但注意inline只是对编译器的一个建议,编译器并不表示一定会采纳,比如当一个函数内部包含对自身的递归调用时,inline就会被编译器所忽略.对于虚函数的inline,编译器也会将之忽略掉,因为内联(代码展…
private继承的意义在于“be implemented in turns of”,这个与上一条款中说的复合模型的第二层含义是相同的,这也意味着通常我们可以在这两种设计方法之间转换,但书上还是更提倡使用复合来进行类的设计. private继承与public的继承是完全不同的,主要体现在两个地方: 其一,public继承在子类中保持父类的访问权限,即父类中是public的成员函数或成员变量,在子类中仍是public,对private或者protected的成员函数或成员变量亦是如此:但priva…
这个条款书上内容说的篇幅比较多,但其实思想并不复杂.只要能理解三句话即可,第一句话是:纯虚函数只继承接口:第二句话是:虚函数既继承接口,也提供了一份默认实现:第三句话是:普通函数既继承接口,也强制继承实现.这里假定讨论的成员函数都是public的. 这里回顾一下这三类函数,如下: class BaseClass { public: ; // 纯虚函数 void virtual ImpureVirtualFunction(); // 虚函数 void CommonFunciton(); // 普通…
这一条款是说的是公有继承的逻辑,如果使用继承,而且继承是公有继承的话,一定要确保子类是一种父类(is-a关系).这种逻辑可能与生活中的常理不相符,比如企鹅是生蛋的,所有企鹅是鸟类的一种,直观来看,我们可以用公有继承描述: class Bird { public: virtual void fly(){cout << "it can fly." << endl;} }; class Penguin: public Bird { // fly()被继承过来了,可以覆…
这个条款的内容很简单,见下面的示例: class BaseClass { public: void NonVirtualFunction() { cout << "BaseClass::NonVirtualFunction" << endl; } }; class DerivedClass: public BaseClass { public: void NonVirtualFunction() { cout << "DerivedClas…
如果说public是一种is-a的关系的话,那么复合就是has-a的关系.直观来说,复合就是在一个类中采用其他类的对象作为自身的成员变量,可以举个例子,像下面这样: class Person { private: string Name; // 复合string类型的变量 PhoneNumber HomeNumber; // 复合PhoneNumber对象 PhoneNumber TelephoneNumber; }; 我们一般会说人有名字,有家庭电话,有手机电话等,但我们一般不会说人是一个名字…
举书上的例子,考虑一个virtual函数的应用实例: class GameCharacter { private: int BaseHealth; public: virtual int GetHealthValue() const // 返回游戏人物的血量 { return BaseHealth; } int GetBaseHealth() const { return BaseHealth; } }; class KnightBoss : public GameCharacter { pub…
还是举书上的例子: void PrettyMenu::changeBackground(std::istream& imgSrc) { lock(&mutex); delete bgImage; ++ imageChanges; bgImage = new Image(imgSrc); unlock(&mutex); } 这段代码大致的意思就是改变背景图片,删掉旧的背景图片,记录修改次数,然后创建新的背景图片.考虑到多线程操作,所以这里用了lock和unlock. 但这里会出现问题…
本章开始讨论内存分配的一些用法,C/C++内存分配采用new和delete.在new申请内存时,可能会遇到的一种情况就是,内存不够了,这时候会抛出out of memory的异常.有的时候,我们希望能够调用自己定制的异常处理函数,这就是本条款要说的. 在声明于<new>的一个标准程序库中,有如下的接口: namespace std { typedef void (*new_handler)(); new_handler set_new_handler(new handler p) throw(…
作为模板部分的结束节,本条款谈到了模板元编程,元编程本质上就是将运行期的代价转移到编译期,它利用template编译生成C++源码,举下面阶乘例子: template <int N> struct Factorial { enum { value = N * Factorial<N - >::value }; }; // 特化版本 template <> > { enum { value = }; }; int main() { cout << Fac…