More C++ Idioms/Interface Class

From Wikibooks, open books for an open world
Jump to: navigation, search

Interface Class[edit]

Intent[edit]

  • To separate an interface of a class from its implementation.
  • Invoke implementation of an abstraction/class using runtime polymorphism.

Also Known As[edit]

Motivation[edit]

Separating an interface of a class from its implementation is fundamental to good quality object oriented software design/programming. For object oriented programming, the principal mechanism of separation is the Interface Class. However C++ (when compared to, say, Java) provides no exclusive mechanism for expressing such a separation. In Java, interface keyword is used to specify only the public methods that are supported by an abstraction. C++ does not have such a keyword but its functionality can be expressed closely using the Interface Class idiom. The idea is to express only the public methods of an abstraction and provide no implementation of any of them. Also, lack of implementation means no instances of the interface class should be allowed.

Solution and Sample Code[edit]

An interface class contains only a virtual destructor and pure virtual functions, thus providing a construct similar to the interface constructs of other languages (e.g. Java). An interface class is a class that specifies the polymorphic interface i.e. pure virtual function declarations into a base class. The programmer using a class hierarchy can then do so via a base class that communicates only the interface of classes in the hierarchy.

class shape   // An interface class
{
  public:
    virtual ~shape();
    virtual void move_x(int x) = 0;
    virtual void move_y(int y) = 0;
    virtual void draw() = 0;
//...
};
 
class line : public shape
{
  public:
    virtual ~line();
    virtual void move_x(int x); // implements move_x
    virtual void move_y(int y); // implements move_y
    virtual void draw(); // implements draw
  private:
    point end_point_1, end_point_2;
//...
};
 
int main (void)
{
  std::vector<shape *> shapes;
  //  Fill up shapes vector somehow.
  for (vector<shape *>::iterator iter (shapes.begin());
       iter != shapes.end();
       ++iter)
  {
    (*iter)->draw();
  }
  //  Clean up shapes vector. (Normally we would use something like boost::shared_ptr to automate cleanup,
  //  this is for illustration only)
}

Every interface class should have a virtual destructor. Virtual destructor makes sure that when a shape is deleted polymorphically, correct destructor of the derived class is invoked. Otherwise there is a good chance of resource leak. Benefit of expressing design using interface classes are many:

  • New shape abstractions can be added without changing the code that depends only on shape interface. For example, Square can inherit from shape and implement the interface methods in its own way. The function main() needs no changes at all.
  • Separation of interface from implementation prevents recompilation of parts of the program that depend only on the interface classes.
  • Dependency Inversion Principle (DIP) states that implementation classes should not depend on each other. Instead, they should depend on common abstraction represented using an interface class. DIP reduces coupling in a object-oriented system.

Known Uses[edit]

Nearly all good object-oriented software in C++!

Related Idioms[edit]

References[edit]

C++ Interface Classes - An Introduction