问题描述:
    不知道在ATL中是怎么避免多继承中的“crystal” 问题的?
  
    因为所有的接口多是从IUnknown继承下来的,所以每个IUnknown中都又一个AddRef函数    那么类似下面的一个结构
    class ATL_NO_VTABLE CSimpleShlExt : 
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CSimpleShlExt, &CLSID_SimpleShlExt>,
public IDispatchImpl<ISimpleShlExt, &IID_ISimpleShlExt, &LIBID_SIMPLEEXTLib>,
public IShellExtInit,
public IContextMenu
         {
         
         }   如果在某一个成员函数中,
   调用一个AddRef 
   由什么机制来保证该调用的正确性?

解决方案 »

  1.   

    QueryInterface的实现保证总是能返回正确的接口指针,即总是返回你所需要的那个vtbl指针,所以能成功。
      

  2.   

    你的线程模型是single thread的,这就决定了,没有 人能够同时创建两个以上你的对象,那么AddRef自然就不可能被同步执行了,结果肯定是正确的了
      

  3.   

    你的线程模型是single thread的,这就决定了,没有 人能够同时创建两个以上你的对象,那么AddRef自然就不可能被同步执行了,结果肯定是正确的了/////////////////////////////////////////
    可能你误解我意思了
    我想知道的是在ATL中,因为它用了多继承来实现COM
    那如何避免
    C++中多继承时的水晶链的问题的?     BASE
          ||
         |  |
        |    |
       D1    D2
        |    |
          ||
          D3
      

  4.   

    使用多继承时,是有这种问题,在生成接口映射表时,用下面几个宏就是解决这个问题的,就是说要显式的指明继承关系,消除多继承歧义就可以了。
    COM_INTERFACE_ENTRY_IID(iid, x)
    COM_INTERFACE_ENTRY2(x, x2)
    COM_INTERFACE_ENTRY2_IID(iid, x, x2)比如在上面的菱形接口关系时,要用COM_INTERFACE_ENTRY_IID(D1, D3)或COM_INTERFACE_ENTRY_IID(D2, D3)取代COM_INTERFACE_ENTRY(D3)
      

  5.   

    sorry,上面写错了一点,应该是用COM_INTERFACE_ENTRY2(D3, D1)或COM_INTERFACE_ENTRY_IID(D3, D2)取代COM_INTERFACE_ENTRY(D3)