Inheriting from a COM class
I'm working in Visual Studio 2005 with a pure unmanaged project (C++). I have a COM class, from a third party, in a OCX file. This class is a control ("widget"). I've been using it through a IDispatch wrapper class generated using the Add Class from Typelib Wizard.
I would like to extend this class in a few ways and public inheritance would be way more practical than compositing (I want th开发者_如何学编程e derived object to expose every single method that the parent class does). The derived class should also be available as a COM component.
Can I do this? If positive, how can I accomplish this?
It is not possible to inherit from COM classes as you can in C++. There are workarounds though:
- COM Aggregates
- Forwarding
COM aggregates is only useful if you want to add an interface (with implementation) to an existing COM class. You cannot intercept calls to the aggregated object.
Forwarding means that if you have an interface IExistingInterface
, you implement your own class that implements IExistingInterface
. In your class you keep a reference to an instance of the object you want to "inherit" from. In your implementation of IExistingInterface
, you forward calls as appropriate to the "inherited" object. This method gives you total control.
Example: (pseudo-code!)
class MyClass : IExistingInterface {
IExistingInterface* m_pInherited;
public:
MyClass() {
::CoCreateInstance(CLSID_OtherImplementation, ..., ..., IID_IExistingInterface, (void**)&m_pInherited);
}
// IExistingInterface methods
HRESULT MethodX() {
// Do some pre processing
HRESULT hr = m_pInherited->MethodX();
if(FAILED(hr))
return hr;
// Do some post processing
return S_OK;
}
};
Edit:
I really recommend that you use ATL to create your COM component. In that case, construct the "inherited" object in FinalConstruct()
rather than the C++ constructor.
You can create a new interface that derives from the first. Your QueryInterface function will need to respond to both GUIDs and deliver the proper pointer. Once you've done that, have your concrete class implement the superset of the functions (i.e. all of the second interface, including everything inherited from the first.)
If your concrete class will also inherit from a concrete class in the library, you're going to have a diamond inheritance pattern. You can search for solutions to that, I'd start here: Diamond inheritance (C++)
精彩评论