Ch10 抽象接口 AbsUI
作为绝缘层的AbsUI
作了程序实现。感觉思路很好。特别是头文件和厂的概念。使得程序很好用。包含头文件很少。用一个抽象类实例就可以搞定一切。但要注意的是:接口函数要声明为 virtual。而且在抽象类中,接口函数要变成纯虚类即 =0;否则报错,因为没有定义。
接口和实现的分离。就是抽象类没有任何的代码实现,仅仅是.h文件。这种分割对于把代码分离到另外的库中(静态或者动态库)而言,是一个非常好的机制。库中需要开发的唯一事情就是抽象接口以及创建新的实现需要的厂(factory),其他的具体实现可以保持比较好的隐藏。
几点细节说明:
- 抽象接口 all functions are virtual functions 且纯虚函数
- 析构函数是虚析构,但不是纯虚,且提供实现,即空函数体{ }
- 若接口和实现紧密耦合,则从抽象接口再派生一个 |<---- MyClass1
《interface》IMyUI <---- CommonImplementation <---|<---- MyClass2
类来提供通用功能 |<---- MyClass3
Ch1
1、多态是的我们可以通过父类的一个引用或者一个指针来指明一个对象
2、是否使用继承?
rule1:继承必须建立一个关系;
rule2:继承一个新类要改变行为而不是数据。容器模型“拥有”一个关系,而继承模型“是”一个关系。
3、在循环中调用一个函数,这个函数最好不要是虚函数,否则开销急增。(性能损失,内存开销增大(看对象实例的多少,及增加一个指针,其实没有多大))
4、每一个类只有一个vtables,而不是每一个对象(实例)一个。但是每一个对象(实例)有一个指针,指向该类的vtables。虚函数额外的开销是 取到对象的 vtable pointer, 再从vtable那里获得入口偏移量(即指向要调用的虚函数的地址)。开销具体多大很难说。跟平台有关,还有cache级别,管道线(pipeline等)。如果指针或引用和对象是同一个类型的,则编译器可以算出函数在vtable中的index,从而直接调用。有编译器 optimize
5、容器和继承的变换:
Mesh <--- PolygonMesh <--- Node <--- GameEntity <--- Enemy
变成:
Mesh <--- PolygonMesh, Node{PolygonMesh}, GameEntity{Node} <--- Enemy
6、阅读建议:
- Eckel.Bruce, Thinking in C++
- Lippman, C++ primer | Inside C++ Object Mode
- Cargill.Tom, C++ Programming Style
- Murray. Robert, C++ Strategies and Tactics
Ch2
1、返回值的 const 限定 和成员函数的const限定如影随形,当返回的是指针的时候(是 by reference 传递,不是 by value)
2、在类中使用 mutable限定符,就可以在 const函数中改变成员变量的值。
3、Reference VS. Pointer : 各有长短利弊。指针对于动态创建和销毁,是引用所不能替代的。两者一个很大的区别在于所引用或指向对象的生存空间。是heap还是stack??
4、C++风格的强制转换:4种
*static_cast : 只能在有联系的指针类型间进行转换。可能在继承体系中转换,但不能转换成继承体系外的类型。
class A; class B: public A; class C;
A* a = new A; B* b = static_cast<B*>(a); // ok!; C* c = static_cast<C*>(a); //error!
C* c = (C*)(a); // old C cast would work,but what is that meaning?
* const_cast
* reinterpret_cast 等价于 C风格的强制类型转换。
* dynamic_cast