Supongamos que tengo una clase que implementa dos o más interfaces COM (exactamente como here):Está utilizando la conversión implícita para un upcast en lugar de QueryInterface() legal con herencia múltiple?
class CMyClass : public IInterface1, public IInterface2 {
};
QueryInterface()
debe devolver el mismo puntero para cada solicitud de la misma interfaz (se necesita una conversión hacia arriba explícita de ajuste de puntero adecuado) :
if(iid == __uuidof(IUnknown)) {
*ppv = static_cast<IInterface1*>(this);
//call Addref(), return S_OK
} else if(iid == __uuidof(IInterface1)) {
*ppv = static_cast<IInterface1*>(this);
//call Addref(), return S_OK
} else if(iid == __uuidof(IInterface2)) {
*ppv = static_cast<IInterface2*>(this);
//call Addref(), return S_OK
} else {
*ppv = 0;
return E_NOINTERFACE;
}
ahora hay dos IUnknown
s en el objeto - una es la base del IInterface1
y el otro es la base de IInterface2
. Y .
Vamos a suponer que llamé QueryInterface()
para IInterface2
- el puntero devuelto será diferente del puntero devuelto cuando llamo para QueryInterface()
IUnknown
. Hasta aquí todo bien. Luego puedo pasar el IInterface2*
obtenido en cualquier función que acepte IUnknown*
y gracias a la conversión implícita de C++ se aceptará el puntero, pero no será el mismo puntero que QueryInterface()
para IUnknown*
recuperaría. De hecho, si esa función llama al QueryInterface()
para IUnknown
inmediatamente después de ser llamada, recuperará un puntero diferente.
¿Es esto legal en términos de COM? ¿Cómo manejo situaciones cuando tengo un puntero a un objeto heredado de forma múltiple y permito un upcast implícito?
Hablando en términos prácticos, nunca he visto ningún código que haga uso de las reglas de identidad COM. Dicho eso, el otro IUnknown * NO es legal, DEBES elegir uno para regresar de QueryInterface. En términos de su propio uso interno y en C++ del objeto de implementación de objetos COM, si no está haciendo el COM de todos modos, cualquier cosa que esté haciendo es legal C++, pero no legitimage COM. –
@Chris Becke: supongo que se requiere identidad para implementar alguna funcionalidad tipo caché. – sharptooth