MFC/COM Objects 5: Using Multiple Inheritance

Nigel Thompson
Microsoft Developer Network Technology Group

March 20, 1995

Abstract

This technical article is the fifth in a series that describes creating and using 32-bit Component Object Model (COM) objects with Visual C++™ and the Microsoft® Foundation Class Library (MFC). This article looks at using multiple inheritance to create COM objects. There is no sample code with this technical article.

Introduction

In the first article of this series ("MFC/COM Objects 1: Creating a Simple Object"), I described how to create a Component Object Model (COM) object using the tools and macros provided with the Microsoft® Foundation Class Library (MFC). If you are familiar with C++, you may well have asked why we needed to use nested classes to define interfaces, when simply inheriting from multiple base classes would have simplified things tremendously. That's what I thought, too, until I did some research into what it would take to create a COM object that used MFC classes, but was based on a multiple inheritance (MI) design. Inasmuch as you may be considering an MI approach yourself, I thought I'd pass on what I learned to help you make a more informed decision.

So the question is: "Can I use multiple inheritance to create COM objects that also use the MFC classes?" There are two answers. The short answer is "Yes," but you'll lock yourself out from being able to use any of the Visual C++™ wizards to add support for OLE Automation. The second answer is a bit longer. . . .

The Long Answer

The "Cairo" group at Microsoft is working on the next major version of Windows NT™, which is based largely on COM objects. This group has decided to use multiple inheritance in creating at least some of its COM objects. To support this, they created a standard COM object class from which other objects can be derived. The base class supports the IUnknown interface and deals with object aggregation as well as implementing table-driven support for the QueryInterface function. Part of the support also includes a standard class for creating class factories for the objects.

Using the "Cairo" group base classes, one can create a COM object by deriving from the standard object base class and also from any interface classes the object supports.

class CMyObject : public CStdComponentObject,
                  public IMyOwnInterface,
                  public ISomeOtherInterface
{
   [...]
};

In the implementation of the class, macros are used to create a static class factory object derived from CStdClassFactory. The class factory keeps a list of all interfaces supported by the object either directly (IMyOwnInterface and ISomeOtherInterface above) or indirectly through the aggregation of other COM objects.

The CStdClassFactory implementation also supplies the DllCreateClassObject and DllCanUnloadNow functions required in any dynamic-link library (DLL) that can provide COM objects.

So using classes derived from CStdComponentObject and CStdClassFactory, we could build a DLL that supported a set of COM objects. The great advantage of using MI to define the objects is that the implementation requires no nested classes and no use of the pThis pointer, which MFC's implementation uses to access the object's members. The IUnknown interface is supplied by the CStdComponentObject base class, so additional interfaces do not need to define or implement the IUnknown methods.

So what's the catch? Well, if all you want to do is create simple COM objects, there isn't one. But if you want to be able to support OLE Automation, you're going to find that you will also need to provide the entire implementation of that yourself because MFC's implementation of OLE Automation (via the IDispatch interface) relies heavily on the fact that MFC's COM objects are derived from the CCmdTarget class. So if you build your COM objects from some other base class, you can't use any MFC COM features at all. Of course, this also means you can't use any ClassWizard support for adding features to your COM objects either.

Summary

Although you can build COM objects using multiple inheritance, and that implementation is much cleaner than MFC's nested class approach, you are going to find it hard to integrate your object code with other MFC classes and features. Because my main focus is on helping you create COM objects using Visual C++ and MFC, I'm going to punt on using MI and concentrate on showing you how to make the most out of what MFC has to offer. To the best of my knowledge, there are no plans for MFC to use an MI approach in the future.