QueryInterface,AddRed,Release是纯虚的表示IUnknown是抽象基类,而并非虚拟基类!! 虚拟基类是,如: public IX : virtual IUnknown { } 这时IUnknown才叫做虚拟基类。那虚拟基类有什么好处呢,请看下面: 比如我还有一个类IY: public IY : virtual IUnknown { }另外还有一个CA类从IX和IY继承,如下; class CA : public IX , public IY { }如果IX、IY都不是从虚拟基类继承的(也就是去掉上面的virtual),则下面这条语句将会产生歧义: CA *pCa;//假设已经得到了pCa指针 IUnknown *pUnk = (IUnknown*)pCa; //这里的pUnk不知道是指向IX的基类IUnknown还是 //IY的基类IUnknown如果采用了虚拟基类,则上面的pUnk将指向一个固定的IUnknown,不会产生歧义!
虚拟基类是,如:
public IX : virtual IUnknown
{
}
这时IUnknown才叫做虚拟基类。那虚拟基类有什么好处呢,请看下面:
比如我还有一个类IY:
public IY : virtual IUnknown
{
}另外还有一个CA类从IX和IY继承,如下;
class CA : public IX , public IY
{
}如果IX、IY都不是从虚拟基类继承的(也就是去掉上面的virtual),则下面这条语句将会产生歧义:
CA *pCa;//假设已经得到了pCa指针
IUnknown *pUnk = (IUnknown*)pCa; //这里的pUnk不知道是指向IX的基类IUnknown还是
//IY的基类IUnknown如果采用了虚拟基类,则上面的pUnk将指向一个固定的IUnknown,不会产生歧义!
public IY : virtual IUnknown
{
}
虚拟继承的IY和一般public继承的类,有什么不同呢?
还有:
如果采用了虚拟基类,则上面的pUnk将指向一个固定的IUnknown,那怎样控制明确pUnk指向一个希望的IUnknown呢?
普通public继承:
-------------- --------------
| IUnknown | | IUnknown |
-------------- --------------
| |
| |
-------------- --------------
| IX | | IY |
-------------- --------------
| |
|-------------------------------|
|
--------------
| CX |
______________虚拟继承:
--------------
| IUnknown |
--------------
|
---------------------------------
| |
-------------- --------------
| IX | | IY |
-------------- --------------
| |
|-------------------------------|
|
--------------
| CX |
______________
你一定是个com高手吧
楼上的解答完全错误。IUnknown不能是虚拟基类是因为如果这样做,那么编译器产生的对象模型是不一样的,这也就违反了COM的最基本要求,即二进制布局相同。可以参考一下《inside c++ object model》,虚拟继承的实现是比较复杂的。
类型转换到IUnknown是没有问题的,因为每个IUnknown都一样,转换到哪个都无所谓。
inside com指出IUnknown接口不是虚拟基类是因为IUnknown接口不能被其他接口虚拟继承,因为虚拟继承是与编译器相关的,不符合二进制标准。
所以在com中所有的其他接口都是直接从IUnknown接口继承,结果就是每个接口的vbtl的前三个函数都是IUnknown接口里的三个函数。
冒汗中 非常之感谢,是我自己粗心!
我的解答确实存在问题,我只是说明了虚拟基类和抽象类的概念!
COM中的确是不允许有虚拟基类存在的!!