OOPortal OOPortal


ATL Development   «Prev 

Adding a COM class

Steps requires to add C++ implementation class for a COM object

Here are the steps requires to add a C++ implementation class for a COM object:
  1. In the Workspace window, the Class View tab is selected. At the top of the ClassView pane, right-click on PhBook classes.
  2. In the pop-up menu, click New Class to open the New Class dialog.
  3. The New Class dialog opens. Under Class Information, type CPhBookObj. Next to Interface type, check Custom.
  4. In the Interfaces section, set Number of interfaces: to 2.
  5. Notice that two interfaces are now named. Next we will change the default names given to the two interfaces. Select the Edit... button in the Interfaces section.
  6. The Edit Interface Information dialog opens. We want to change the name of the first interface to IReadPhBook. Double-click on IPhBookObj in the Interfaces Names: list box. Replace IPhBookObj with IReadPhBook. Change the name of the second interface. Double-click on IPhBookObjInt2 and replace it with IManagePhBook. Once the interface names have been changed, click OK in the Edit Interface Information dialog.
  7. We return to the New Class dialog. Make sure the Aggregatable check box at the bottom of the New Class dialog is checked. Click OK to accept the new COM object.
  8. The new COM object is completed. The object and its two interfaces are added to the PhBook classes. This is the end of the simulation.

COM programming is interface-based

The most important concept to understand about COM programming is that it is interface-based. You do not need real COM or even Microsoft runtime support to use interface-based programming. All you need is some discipline. In the following spaceship example, we start with a single class named CSpaceship that implements several functions. C++ developers usually sit down at the computer and start typing a class like this:
class CSpaceship
{
void Fly();
int	& GetPosition();
};

With interface-based COM development the procedure is a little different . Instead of writing the class directly, interface-based programming involves spelling out an interface before implementing it. The Fly() and GetPosition() functions were moved into an abstract base class named IMotion.
struct IMotion
{
virtual void Fly() = 0;
virtual int& GetPosition() = 0;
};

Then we inherit the CSpaceship class from the IMotion interface like this:
class CSpaceship : IMotion
{
void Fly();
int& GetPosition();
};

interface separates Implementation

Notice that at this point the motion interface has been separated from its implementation. When practicing interface development, the interface comes first. You can work on the interface as you develop it, making sure it is complete. But once the interface has been published and is being used by other developers, the interface is set in stone and cannot change. This subtle distinction between class-based programming and interface-based programming seems to introduce some programming overhead. However, it turns out to be one of the key points to understanding COM. By collecting the Fly() and the GetPosition() functions in an interface, you have developed a binary signature. That is, by defining the interface ahead of time and talking to the class through the interface, client code has a potentially language-neutral way of talking to the class. Gathering functions together into interfaces is itself quite powerful. Imagine you want to describe something other than a spaceship, an airplane, for example. It's certainly conceivable that an airplane would also have Fly() and GetPosition() functions. Interface programming provides a more advanced form of polymorphism, polymorphism at the interface level, not only at the single-function level. Separating interface from implementation is the basis of interface-based development. The Component Object Model is centered on interface programming. COM enforces the distinction between interface and implementation. In COM, the only way client code can talk to an object is through an interface. However, gathering functions together into interfaces isn't quite enough. There's one more ingredient needed, a mechanism for discovering functionality at runtime.