Visual C++ 6 Unleashed

Visual C++ 6 Unleashed

By MICKEY WILLIAMS and David Bennett

The Active Template Library

The Active Template Library (ATL) is a recent addition to the Visual C++ product. It came about primarily as a result of the explosive growth of the Internet and Microsoft's ActiveX strategy, which originally was developed to encourage the use of COM-based components on the Internet and corporate intranets. In order for these controls to make sense in the Internet market, the controls have to be small and compact so that they can be downloaded from Web servers quickly. It certainly is possible to build these controls with MFC, but MFC applications are characteristically large and require large support DLLs. Another alternative to MFC was needed that could create smaller controls without the need for support DLLs. The ATL is the alternative Microsoft has provided.

ATL and MFC differ in their approaches. Both libraries rely on C++ capabilities, but that is where their similarities end. MFC is built on the concept of a class hierarchy. Most of the MFC classes derive from other classes, which eventually derive from CObject. This hierarchy allows classes to inherit many behaviors from their ancestors. As an example, consider the CButton class. It implements a handful of new methods but inherits a tremendous amount of behavior from the CWnd class. CWnd, in turn, inherits from CCmdTarget, which inherits from CObject. A strategy like this has a few interesting characteristics:

ATL takes a different approach than MFC. It is based on the concept of a template. A template is a way of capturing an algorithm in the form of a pattern. For example, if you have a mathematical formula such as x + y + z that you want to implement for integers and floating-point numbers, you could create two classes:

class HighTechInteger
{
public:
   HighTechInteger();
   ~HighTechInteger();
   integer Calculate( int x, int y, int z ) {  return( x+y+z ); }
};

class HighTechFloat
{
public:
   HighTechFloat();
   ~HighTechFloat();
   float Calculate( float x, float y, float z ) {  return( x+y+z ); }
};

Notice how both implementations have identical algorithms for their Calculate methods. Given these classes, however, you could never use the HighTechInteger class to handle floating-point numbers. You must maintain two separate classes. This creates opportunities for bugs to be introduced if both classes are not kept in sync. The alternative is to create a template:

template <Type> class HighTech
{
public:
   HighTech();
   ~HighTech();
   Type Calculate( Type x, Type y, Type z ) {  return( x+y+z ); }
};

HighTech<int>   htInteger;
HighTech<float> htFloat;

Notice how this unifies the source code base and increases code reliability because the algorithm is implemented only once.

Another feature of C++ that ATL uses is multiple inheritance. C++ allows one class to inherit from several parent classes. Grady Booch, in his book Object-Oriented Analysis and Design with Applications (Addison-Wesley, 1998), describes special lightweight classes designed for multiple inheritance as mixin classes. C++ multiple inheritance can be used in many ways, but classes designed for the mixin approach typically are thin, focused, and easily reusable. Let's consider a mixin scenario:

class subtractMixin
{
public:
   int Sub( int x, int y );
};

class MyCoolClass : public CoolBaseClass
{
public:
   int Add( int x, int y );
};
class MyFriendsClass : public CoolBaseClass
{
public:
    int Mult( int x, int y );
}

Suppose that the subtractMixin class is a useful, reusable algorithm that can be used in a variety of situations—it can be mixed in with many different classes. One way to implement this kind of feature would be as a separate class that could be inherited from to obtain the desired behavior. This class would be considered a mixin class. Mixin classes do not necessarily provide usefulness by themselves but are useful as additive behaviors. Now suppose that you want your MyCoolClass to have the capability to subtract as well as add. You could define another method in the MyCoolClass class or just inherit the behavior from subtractMixin:

class MyCoolClass : public CoolBaseClass, public subtractMixin
{
public:
   int Add( int x, int y );
};

In addition, you could add subtract behavior to MyFriendsClass or any other class by inheriting from subtractMixin. It is not very useful to create an instance of subtractMixin by itself, however.

ATL uses both the template concept and the mixin concept. Because many of the COM interfaces are small and clean, they lend themselves to being used as mixin classes. The ATL strategy has these characteristics:

ATL is discussed in more detail in Part VII, "Using the Active Template Library."

ATL Classes Required for Active Document Support

The following list provides an overview of some of the ATL classes you will see in the ACTIVEDOC sample program:

Share ThisShare This

Informit Network