支持“编译依存性最小化”的一般构想是:相依于声明式,不要相依于定义式.基于此构想的两个手段是Handle classes 和 Interface classes. 程序库头文件应该以“完全且仅有声明式”(full and declaration-only forms)的形式存在.这种做法不论是否涉及templates都适用.…
NOTE1: 1.支持“编译依存性最小化”的一般构想是:相依于声明式,不要相依于定义式.基于此构想的两个手段是Handle classes 和 Interface classes. 2.程序库头文件应该以“完全且仅有声明式”(full and declaration-only forms)的形式存在.这种不论是否涉及templates都适用.…
下面来谈谈书中的第二部分,用Interface Classes来降低编译的依赖.从上面也可以看出,避免重编的诀窍就是保持头文件(接口)不变化,而保持接口不变化的诀窍就是不在里面声明编译器需要知道大小的变量,Handler Classes的处理就是把变量换成变量的地址(指针),头文件只有class xxx的声明,而在cpp里面才包含xxx的头文件.Interface Classes则是利用继承关系和多态的特性,在父类里面只包含成员方法(成员函数),而没有成员变量,像这样: // Person.h…
从本条款开始,就进入了全书的第七部分:模板与泛型编程.模板与泛型在C++中是非常重要的部分,还记得本书第一章时,把C++视为一个联邦,它由四个州政府组成,其中一个政府就是模板与泛型了. 本条款是一个介绍性质的条款,内容不难,只需要讲清楚两个概念就行了,即什么是隐式接口,什么是编译期多态. 隐式接口是相对于函数签名所代码的显式接口而言的.当我们看到一个函数签名(即函数声明),比如说: string GetNameByStudentID(int StudentID); 我们就知道这个函数有一个整型的…
在栈空间的临时成员变量在函数生命期结束后无法传出 friend A& operator*(const A& a, const A& b) { A temp; temp.data = a.data*b.data;//a,b的成员变量相乘 return temp; } 既然栈空间不行,试试堆空间 friend A& operator*(const A& a, const A& b) { A *temp=new A; temp.data = a.data*b.da…
学过基本程序课的同学都知道,inline是内联的关键字,它可以建议编译器将函数的每一个调用都用函数本体替换.这是一种以空间换时间的做法.把每一次调用都用本体替换,无疑会使代码膨胀,但可以节省函数调用的成本,因为函数调用需要将之前的参数以堆栈的形式保存起来,调用结束后又要从堆栈中恢复那些参数. 但注意inline只是对编译器的一个建议,编译器并不表示一定会采纳,比如当一个函数内部包含对自身的递归调用时,inline就会被编译器所忽略.对于虚函数的inline,编译器也会将之忽略掉,因为内联(代码展…
举个例子: class Student { private: int ID; string name; public: string& GetName() { return name; } }; 这是一个学生的类,类里面有两个成员变量,一个是学生ID,用整数表示,另一个是姓名,用string表示.有一个公有的方法GetName(),获得学生的名字,根据条款20所说的,使用引用可以防止资源不必要地拷贝,那么在返回值这边就用string&.但现在问题来了,这个函数只是想返回学生的姓名,并不想用…
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()被继承过来了,可以覆…