1. 用C++语言自己来表达设计上的约束条件,而不是用注释或文档。比如如果一个类在设计时绝不打算成为derived classes,那么就不应该只是在头文件class上端摆一行注释就好,而是应该以C++语法来阻止派生,参考条款26。如果一个类要其所有对象实体都必须于堆内产生,那么按照27厉行约束。如果copying和assignment对某个class没有意义,将其设为private。
2. 未来时态的考虑不是问一个类现在正被怎么使用,而是问这个类是被设计为怎么去使用的.请努力让classes的操作符和函数拥有自然的语法和直观的语义。请和内建类型的行为保持一致:如果有疑惑,不妨看看ints有怎样的表现。
3. 未来时态的考虑只是简单地增加了一些额外约束:
* 提供完备的类,即使某些部分现在还没有被使用。如果有了新的需求,你不用回过头去改它们。请为每一个class处理assignment和copy construction动作。
* 将你的接口设计得便于常见操作并防止常见错误。使得类容易正确使用而不易用错。
例如,阻止拷贝构造和赋值操作,如果它们对这个类没有意义的话。防止部分赋值。
* 如果没有限制你不能通用化你的代码,那么通用化它。
例如,如果在写树的遍历算法,考虑将它通用得可以处理任何有向不循环图。
4、注意这一章的小示例。
编程点滴:抽象类的派生类不能是抽象类;实现纯虚函数一般不常见,但对纯虚析构函数,它必须实现
1. 绝大部分纯虚函数都没有实现,但纯析构函数是个特例.它们必须被实现,因为它们在派生类析构函数被调用时也将被调用.
2. 如果有两个实体类C1和C2,并且C2公有继承C1,那么你应该将两个类的继承层次改为三个类的继承层次,通过创造一个新的抽象类A,并将C1和C2都从它继承.这种修改的重要价值是强迫你确定抽象类. 其目的是,确认有用的抽象,并强迫它们放入抽象类这样的实体.
3注意,只有在设计出得类能被将来的类从它继承而不需要它做任何修改时,你才能从抽象类中获得好处.。
4.非尾端类应该是抽象类在处理外来的类库,可能不得不违反这个规则
1混合编程的指导原则:
确保C++和C编译器产生兼容的obj文件
将在两种语言下都使用的函数申明为extern C
只要可能,用C++写main()
总用delete释放new分配的内存;总用free释放malloc分配的内存
将在两种语言间传递的东西限制在用C编译的数据结构的范围内;这些结构的C++版本可以包含非虚成员函数
2. 确保C++编译器和C编译器兼容
名变换
-------------
1. 名变换,就是C++编译器给程序的每个函数换一个独一无二的名字。在C中,这个过程是不需要的,因为没有函数重载,但几乎所有C++程序都有函数重名.因此C++编译器通常会对函数进行名变换.这需要一个办法来告诉C++编译器不要在这个函数上进行名变换.
2. 要禁止名变换,需要使用C++的extern "C"指示符.
不要将extern 'C'看作是申明这个函数是用C语言写的,应该看作是申明在个函数应该被当作好象C写的一样而进行调用。
1. extern"C" void simulate(int iterations);
2. extern"C"{
3. void drawLine(int x1, int y1, int x2, inty2);
4. void twiddleBits(unsigned char bits);
5. void simulate(int iterations)
6. }
静态初始化
-----------------
1. 在C++的main执行前和执行后都有大量代码被执行。
静态的类对象和定义在全局的、命名空间中的或文件体中的类对象的构造函数通常在main被执行前就被调用。
通过静态初始化产生的对象也要在静态析构过程中调用其析构函数;这个过程通常发生在main结束运行之后。
2. 如果main()不是用C++写的,那么前后的代码可能就不会被执行,从而C++库中的静态对象可能没有被初始化和析构.
最好的办法是将C的main()改名,然后在C++的main()中调用C的main()函数
动态内存分配
-------------------
1. 将C++的new和delete与malloc和free进行严格的分离
数据结构的兼容性
-----------------------
1. 两种语言间的函数可以安全地交换指向对象的指针和指向非成员的函数或静态成员函数的指针
2. C++中非虚函数的的struct或class的对象兼容了它们在C中的孪生版本(其定义只是去掉了这些成员函数的声明)
在C++的struct中增加虚函数,会使得对象使用一个不同的内存结构,这就跟C不兼容了.
从其它结构(或类)进行继承的结构,通常也改变其内存结构,所以有基类的结构也不能与C函数交互。
STL 基于三个基本概念:包容器(container)选择子(iterator)和算法(algorithms)包容器是被包容的对象的封装;选择子是类 指针的对象,让你能如同使用指针操作内建类型的数组一样操作STL的包容器;算法是对包容器进行处理的函数,并使用选择子来实现