随便扯扯

针对博客里面的问题随便说几句,其实COM我没怎么用过

http://www.cnblogs.com/mumuliang/archive/2011/01/14/1935792.html

 

 

对于疑问1:假设不用纯虚类,类的使用者可以new来创建其实例。那么如果有一天IFastString的开发者突然觉得这个类的实现加一个私有成员变量会更加高效。然后灾难就来了,IFastString这个类的大小变了,于是所有的使用IFastString的人都需要重新编译他的代码。想象一下,windows有一点点的升级,都要重新编译所有的应用程序是多么的可怕。

 

对于疑问2:出于疑问1的考虑,COM必然选择纯虚类作为接口。类的使用者不知道类的实现,所以无法创建类的实例(没法new). 于是COM实现了一种create by name的机制,把类的创建交给了类的实现者。既然类的创建是一个函数CoCreateInstance而不是直接调用new和构造函数,那么摧毁这个类的时候也就不应该调用析构函数,析构函数的调用者自然应该是构造函数的调用者。假设是类的使用者调用了delete p; 那么万一类的实现者重载了delete, 这两个delete根本不通用怎么办。

疑问2的补充:

我不同意他的理由。虚析构函数和其他虚函数的实现本没有什么区别。或者说标准本没规定在实现他们上需要有什么区别。

我理解是这样的,在C++里面new和delete必须是对应的。怎么样new出来的东西,就该怎么delete.

假设类的实现者使用如下的方式创建类实例

B *p = new B;

B *pp = new B[10];

那么类的使用者怎么调用delete呢? 所以,类的销毁只能交给类的实现者来做。

 

还有,delete是个操作符(operator),他本身不是虚函数。delete的逻辑是这样的

先调用类的析构函数

然后调用operator delete去回收内存。

(注:C++中delete和operator delete是两个东西,delete不可被重载,而operator delete可以被重载,同样的也存在new/operator new)

既然operator delete可以被重载,那么问题就出来了。类的使用者的operator delete不一定能够和类的实现者的operator new匹配。

既然不该由类的使用者销毁对象实例,那么也就没有理由把析构函数作为虚函数了,否则类的使用者调用了析构函数,回头类的实现者再调用一次析构函数不就麻烦了。

 

 

posted @ 2011-01-14 22:00  嗷嗷  阅读(226)  评论(4编辑  收藏  举报