|
|
So far, we have carefully avoided a precise definition of the term ``component.'' We will now attempt to give one.
The C language, as the popular saying goes, was designed for writing ``industrial strength software.'' Sadly, however, no collection of components on the industrial scale envisioned by McIlroy has appeared in the twenty years of C's existence. With the results of twenty years of programming language research in hand, we now know the reason why: C simply does not provide adequate mechanisms for building components at the appropriate level of integration for industrial use.
McIlroy, writing from his 1960's vantage point, equated components with ``Fortran subroutines.'' Languages that trace their ancestry to Simula (including C++) offer a much more powerful mechanism for component building: the class. A class corresponds roughly to a data type; classes allow programmers to add new data types to a language, just as subroutines allow programmers to add new operations.
For example, the solution using the String component that we presented earlier declared three variables of class (type) String:
#include <String.h> String machine, service, dialstring;If you look in String.h, you will find the definition for class String. It looks something like this:
class String{ representation details public: // Constructors, destructor String(); String(const char* p); String(const char* p, unsigned n);lots of other stuff };
However, you will also find other definitions in String.h, in addition to class String. These supplement the class definition to form a complete ``string package.'' For example, there is an auxiliary class Substring used by operations that manipulate parts of Strings. Without Substrings, such operations would be inefficient at best and unimplementable at worst. Other components may need several primary class definitions (together with auxiliary definitions) in order to form a complete package.
Formally, a component is a collection of facilities, usually (but not necessarily) including one or more classes, that are packaged as a unit because programmers find the facilities useful together. These facilities can be functions, typedefs, enumerations, constants, and so on: in general, any C++ programming language entity that may be defined in a C++ header file can be provided as a facility of a component.
A component's interface is (usually) defined in a single header file. To use any of String's facilities, for example, you only need to include the single header file String.h:
#include <String.h> you can now use class String as well as other facilities of the String component
Some components are considerably richer in composition than the String component. For example, the Time component includes three primary classes Time, Duration, and Place in addition to other, non-class facilities. Why three classes? Because time calculations tend to employ all three types of values, as illustrated by the fact that the difference between two Times at two different Places is a Duration. To obtain any of the facilities of the Time component, simply include the component header file:
myprog.c #include <Time.h> Time t; Duration d; Place p;A component also has zero or more object files which are stored in a library archive for efficient linking. A component may also have template definition source files which are used when the component's templates are instantiated.