next up previous
Next: Defining the implementation Up: From Modula-2 ADT's to Previous: Separation of interface

Defining the interface

The header file should, just like in Modula-2, reveal as little as possible of the implementation. But in contrary to Modula-2, in C++ it's very hard to hide everything of the implementation, as we'll see later on.

An example of the interface of a stack as it could be defined in Modula-2:

DEFINITION MODULE IntStacks;

(* Elements: Although the elements could be of a variety of types, for
    simplicity we assume that they are of type INTEGER *)

(* Structure: Linear, Last in first out *)

(* Domain: The number of elements in a stack is bounded to a certain
    maximum. *)

TYPE 
    IntStack;                  (* Opaque type to represent a Stack. *)

PROCEDURE Push(VAR S: IntStack; e: INTEGER);
(* pre  - S is not full.
   post - S includes e as its most recently arrived element. *)

PROCEDURE Pop(VAR S: IntStack; VAR e: INTEGER);
(* pre  - S is not empty.
   post - e is the most recently arrived element of S-pre;
          S no longer contains e. *)

PROCEDURE Empty(S: IntStack): BOOLEAN;
(* post - TRUE : S has no elements
          FALSE: S has at least one element *)

PROCEDURE Full(S: IntStack): BOOLEAN;
(* post - TRUE : S has reached its bound
          FALSE: S can at least contain one more element *)

PROCEDURE Create(VAR S: IntStack): BOOLEAN;
(* pre  - S does not exist
   post - TRUE : S has been created, S is empty
          FALSE: there was not enough memory left to create S *)

PROCEDURE Terminate(VAR S: IntStack);
(* post - S-pre does not exist. *)

END IntStacks.

A typical header file of the same ADT might look like

// intstack.h

#ifndef _INTSTACK_H_
#define _INTSTACK_H_

class intstack
{
public:
    intstack();
        // post - The stack has been created, the stack is empty
    ~intstack();
        // post - The stack-pre does not exist

    void push(int e);
        // pre  - The stack is not full.
        // post - The stack includes e as its most recently arrived element.
    void pop(int& e);
        // pre  - The stack is not empty.
        // post - e is the most recently arrived element of the stack-pre;
        //        the stack no longer contains e.
    bool empty();
        // post - true : The stack has no elements.
        //        false: The stack has at least one element.
    bool full();
        // post - true : The stack has reached its bound.
        //        false: The stack can at least contain one more element.

private:
    int* stack_;
    int  top_;
};

#endif

The #ifndef/#define construction is used to prohibit multiple inclusions of the header file.gif

The interfaces in Modula-2 and C++ are very similar, but they differ on some important points. The most noticeable difference is the absence of a parameter of the stack type in all member functions. This is because functions do not work on an instance, but are requests to an instance to perform some action. Compare calling the Full function on a variable in Modula-2:

:
    IF Full(MyStack) THEN
:
to asking a stack-instance if it's full:
:
    if (mystack.full())
:

Another difference is the overall structure of the interface. In Modula-2, all functions are in fact seperate functions with one common parameter. In a C++ class, the functions are all member functions of the ADT and are therefore declared within the class intstack { ... }; statement.

The third difference is the exposure of the internal variables of a class. The only thing known about the type IntStack in the Modula-2 interface is the fact that it exists; it's completely opaque. But in C++, all variables used in the implementation have to be declared in the interface, thereby making it virtually impossible to create an ADT that's really abstract. Making these member variables private will shield them from being used directly by a user.

The last difference is the names of the functions to create and destroy instances of the ADT. C++ offers constructors and destructors, so you should not give them other names like Create or Terminate.



next up previous
Next: Defining the implementation Up: From Modula-2 ADT's to Previous: Separation of interface



SE Praktikum
Tue Aug 13 13:10:22 MET DST 1996