modo hijo herencia ejemplos derivadas derivada clases clase c++ visual-studio com atl classwizard

c++ - hijo - ¿Cómo hacer una clase COM de ATL derivada de una clase base?



herencia java (2)

El asistente "objeto simple ATL" no proporciona una forma de especificar que una nueva clase se deriva de un cocllass existente y su interfaz. En Visual Studio 2008, ¿cómo hago una nueva clase COM de ATL derivada de una existente (es decir, Base implementa IBase , y quiero crear una nueva clase derivada derivada de Base que implementa IDerived , donde IDerived se deriva de IBase ).

Actualización: suena simple, pero una clase ATL generada por asistente tiene hasta seis clases base, un mapa COM y un mapa de punto de conexión. ¿Cuál de estas clases base y mapas deberían repetirse en la clase derivada? Si los mapas se repiten en la clase derivada, ¿deberían contener el contenido del mapa de la clase base o solo los elementos adicionales? ¿Importa el orden de las clases base? ¿Qué pasa con FinalConstruct() y FinalRelease() ? ¿Deberían DECLARE_PROTECT_FINAL_CONSTRUCT y DECLARE_REGISTRY_RESOURCEID repetirse en la clase derivada?

Aquí hay una clase base de muestra que está vacía, excepto por todos los repetidores. Ahora, ¿cómo debería ser la clase derivada?

class ATL_NO_VTABLE CBase : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CBase, &CLSID_Base>, public ISupportErrorInfo, public IConnectionPointContainerImpl<CBase>, public CProxy_IBaseEvents<CBase>, public IDispatchImpl<IBase, &IID_IBase, &LIBID_ExampleLib, /*wMajor =*/ 1, /*wMinor =*/ 0> { public: CBase() { } DECLARE_REGISTRY_RESOURCEID(IDR_Base) BEGIN_COM_MAP(CBase) COM_INTERFACE_ENTRY(IBase) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(ISupportErrorInfo) COM_INTERFACE_ENTRY(IConnectionPointContainer) END_COM_MAP() BEGIN_CONNECTION_POINT_MAP(CBase) CONNECTION_POINT_ENTRY(__uuidof(_IBaseEvents)) END_CONNECTION_POINT_MAP() // ISupportsErrorInfo STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid); DECLARE_PROTECT_FINAL_CONSTRUCT() HRESULT FinalConstruct() { return S_OK; } void FinalRelease() { } }; OBJECT_ENTRY_AUTO(__uuidof(Base), CBase)


Edite el código que generan los asistentes. Si desea que un objeto se derive de interfaces adicionales, agregue estas clases base a la declaración de clase resultante.


Solo una sugerencia: si su objeto COM no necesita hacer nada especial con cosas relacionadas con COM, entonces puede implementar un código tal que la lógica real que hace su clase base COM esté encapsulada en otra antigua clase simple de C ++, digamos CBaseLogic.

CBaseLogic : IBase class ATL_NO_VTABLE CBase : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CBase, &CLSID_Base>, public ISupportErrorInfo, public IConnectionPointContainerImpl<CBase>, public CProxy_IBaseEvents<CBase>, public IDispatchImpl<IBase, &IID_IBase, &LIBID_ExampleLib { CBaseLogic m_LogicObj; /* Method calls are simply forwarded to this member */ }; CDerivedLogic : public CBaseLogic class ATL_NO_VTABLE CDerived : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CDerived, &CLSID_Base>, public ISupportErrorInfo, public IConnectionPointContainerImpl<CDerived>, public CProxy_IBaseEvents<CDerived>, public IDispatchImpl<IBase, &IID_IBase, &LIBID_ExampleLib { CDerivedLogic m_LogicObj; };

Esto logra lo que intenta hacer con la ventaja adicional de

  1. Mantiene su lógica de programa real separada de la infraestructura / embalaje (COM)
  2. Hace que la plataforma lógica real sea independiente.
  3. El futuro mantenedor no necesita entender su hábil hack COM
  4. Mantiene la lógica de tu programa limpia y alejada de la sintaxis COM, mejorando la legibilidad
  5. Hace que la reutilización de la lógica real sea más fácil en otras formas de empaquetado, por ejemplo, como una DLL C