今天开始写一些自己的读书心得,希望能坚持下去。
第一章
COM
是更好的
C++
为什么说
COM
是更好的
C++
。答:因为
COM
是可重用的组建结构。
C++
通过
class
的方式进行软件重用,以源代码的形式进行分发。这就带来两个问题:
1.
如果很多程序都需要使用这个
class
的话,每个程序都需要占用相同大小的资源。
2.
一旦这个
class
需要更新的话,目标程序需要重新编译链接。
如何解决上面的问题?答:把
class
以动态链接库
(DLL)
的形式包装起来,使
class
的所有方法从
DLL
中引出来。这样一来上面的两个问题都没有了,但又会带来一个新的问题:
l
这个
DLL
升级的时候,比如新加一个成员变量的话,原来的
EXE
有可能会崩溃。
如何解决上面的问题?答:把接口和实现分离开来。也就是说,另外定义一个
class A
,用这个类来创建另外一个类
B
的实例。这样的话
class A
只需要保留一个
class B
的指针变量就可以了。但是这样并不是非常完美:
l
每次
class B
需要增加一个成员函数的时候,相应的
class A
也需要增加相应的接口。
如何解决上面的问题?答:抽象基类作为二进制接口。也就是说,外部程序包含抽象基类的声明,实现类继承这个抽象基类。这样就需要另外定义一个全局函数来创建实现类。这样的话,问题到解决了。
但是还是需要注意另外三个问题:
1.
运行时多态性
2.
对象扩展性
3.
资源管理
我们走到了哪儿?
这一章从一个简单的
C++
类开始,然后一步步讨论如何把这个类做成可重用的二进制组件。第一步是以动态链接库
(DLL)
的形式来发布这个类,以便从物理上把这个类的包装与客户的包装脱离开来。然后我们使用接口和实现的概念,把数据类型的实现细节封装到二进制防火墙后面,使得对象的布局接口能够随时间而进化,但无须要求客户重新编译。在使用抽象类作为定义接口的方法之后,这道防火墙便以
vptr
和
vtbl
的形式出现了。接下来,我们使用
LoadLibrary
和
GetProcAddress
,在运行时动态的选择同一接口的不同实现
(
呈现了运行时的多态性
)
。最后,我们使用与
RTTI
类似的结构,在运行时动态地询问对象,以确定对象实际上是否实现了指定的接口。这种结构使我们能够扩充接口的现有版本,并且也可以从单个对象暴露多个不相关的接口。
简而言之,我们刚刚设计了组建对象模型
(COM
:
Component Object Model)
。