Derivation from an Abstract Base Class

Table of contents:

An abstract base class is used to encapsulate common features of concrete classes. An abstract class cannot be instantiated. Nevertheless, this scheme is quite useful and efficient for organizing our knowledge of the vastly complex biological world. In the simplified taxonomic organization chart shown in Figure 6.2, we can see that a primate is a mammal that has certain additional characteristics, a gorilla is a hominid with certain additional characteristics, and so forth.

Figure 6.2. Animal taxonomy

A concrete class represents a particular kind of entity, something that really exists and can be instantiated. For example, walking through the woods you will never encounter a real, live animal that is completely described by the designation Carnivora or Felidae. You may, depending on where you walk, find a lion, a siamese cat, or a common housecat (Felis silvestris). But there is no instance of a Hominidae (i.e., of a base class) in the concrete world that is not also an instance of some particular species. If a biologist ever finds a concrete instance that does not fit into an existing species definition, then that biologist may define and name a new species and become famous.

To summarize, the more general categories (class, order, family, subfamily) are all abstract base classes that cannot be instantiated in the concrete world. They were invented by people to help with the classification and organization of the concrete classes (species).

Back to Programming

At first it might seem counterintuitive to define a class for an abstract idea that has no concrete representative. But classes are groupings of functions and data, and are useful tools to enable certain kinds of organization and reuse. Categorizing things makes the world simpler and more manageable for humans and computers.

As we study design patterns and develop frameworks and class libraries, we will sometimes design inheritance trees where only the leaf nodes can be instantiated, and the inner nodes are all abstract.

Once again, an abstract base class is a class that is impossible and/or inappropriate to instantiate. Features of a class that tell the compiler to enforce this rule are:

  • There is at least one pure virtual function.
  • There are no public constructors.

Figure 6.3 shows a class hierarchy with an abstract base class, Shape. Shape is abstract because it contains pure virtual functions.

Figure 6.3. Shapes UML diagram

A pure virtual function has the following declaration syntax:

virtual returnType functionName(parameterList)=0;

Example 6.13 shows the base class definition.

Example 6.13. src/derivation/shape1/shapes.h

[ . . . . ]

class Shape { <-- 1
 public:
 virtual double area() = 0; <-- 2
 virtual QString getName() = 0;
 virtual QString getDimensions() = 0;
 virtual ~Shape() {}
};
 

(1)an abstract base class

(2)pure virtual function

getName(), area(), and getdimension() are all pure virtual functions. Because they are defined to be pure virtual, no function definition is required in the Shape class. Any concrete derived class must override and define all pure virtual base class functions for instantiation to be permitted. In other words, any derived class that does not override and define all pure virtual base class functions is, itself, an abstract class. Example 6.14 shows the derived class definitions.

Example 6.14. src/derivation/shape1/shapes.h

[ . . . . ]

class Rectangle : public Shape {
 public:
 Rectangle(double h, double w) :
 m_Height(h), m_Width(w) {}
 double area();
 QString getName();
 QString getDimensions();

 protected: <-- 1
 double m_Height, m_Width;
};

class Square : public Rectangle {
 public:
 Square(double h) : Rectangle(h,h) {} <-- 2
 double area();
 QString getName();
 QString getDimensions();
};
 

(1)We want to access m_Height in Square class.

(2)Base class name in member initialization listpass arguments to base class ctor

Rectangle, Circle, and Square are derived from Shape. Their implementations are shown in Example 6.15.

Example 6.15. src/derivation/shape1/shapes.cpp

#include "shapes.h"

 double Circle::area() {
 return(3.14159 * m_Radius * m_Radius);
 }
 double Rectangle::area() {
 return (m_Height * m_Width);
 }
 double Square::area() {
 return (Rectangle::area()); <-- 1
 }
[ . . . . ]
 

(1)calling base class version on 'this'

We provide some client code to exercise these classes in Example 6.16.

Example 6.16. src/derivation/shape1/shape1.cpp

#include "shapes.h"
#include 
#include 

void showNameAndArea(Shape* pshp) {
 qDebug() << pshp->getName()
 << " " << pshp->getDimensions()
 << " area= " << pshp->area();
}

int main() {
 Shape shp; <-- 1

 Rectangle rectangle(4.1, 5.2);
 Square square(5.1);
 Circle circle(6.1);

 qDebug() << "This program uses hierarchies for Shapes";
 showNameAndArea(&rectangle);
 showNameAndArea(&circle);
 showNameAndArea(&square);
 return 0;
}
 

(1)ERROR: Instantiation is not allowed on classes with pure virtual functions.

In the global function showNameAndArea() the base class pointer, pshp, is successively given the addresses of objects of the three subclasses. For each address assignment, pshp polymorphically invokes the correct getName() and area() functions. Example 6.17 shows the output of the program.

Example 6.17. src/derivation/shape1/shape.txt

This program uses hierarchies for Shapes

 RECTANGLE Height = 4.1 Width = 5.2 area = 21.32
 CIRCLE Radius = 6.1 area = 116.899
 SQUARE Height = 5.1 area = 26.01


Inheritance Design

Part I: Introduction to C++ and Qt 4

C++ Introduction

Classes

Introduction to Qt

Lists

Functions

Inheritance and Polymorphism

Part II: Higher-Level Programming

Libraries

Introduction to Design Patterns

QObject

Generics and Containers

Qt GUI Widgets

Concurrency

Validation and Regular Expressions

Parsing XML

Meta Objects, Properties, and Reflective Programming

More Design Patterns

Models and Views

Qt SQL Classes

Part III: C++ Language Reference

Types and Expressions

Scope and Storage Class

Statements and Control Structures

Memory Access

Chapter Summary

Inheritance in Detail

Miscellaneous Topics

Part IV: Programming Assignments

MP3 Jukebox Assignments

Part V: Appendices

MP3 Jukebox Assignments

Bibliography

MP3 Jukebox Assignments



An Introduction to Design Patterns in C++ with Qt 4
An Introduction to Design Patterns in C++ with Qt 4
ISBN: 0131879057
EAN: 2147483647
Year: 2004
Pages: 268

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net