6.3. Derivation from an Abstract Base Class

[ fromfile: inheritance-intro.xml id: abstractbaseclass ]

Figure 6.2.  Animal Taxonomy

Animal Taxonomy

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.

Figure 6.3.  Shapes UML Diagram

Shapes UML Diagram

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.


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();
};

class Circle : public Shape {
 public:
    Circle(double r) : m_Radius(r) {}
    double area();
    QString getName();
    QString getDimensions();
 private:
    double m_Radius;
};

1

We want to access m_Height in Square class.

2

Base class name in member initialization list - pass arguments to base class ctor.


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

#include "shapes.h"
#include <math.h>
    double Circle::area() {
        return(M_PI * m_Radius * m_Radius); 1
    }

    double Rectangle::area() {
        return (m_Height * m_Width);
    }

    double Square::area() {
        return (Rectangle::area());         2
    }
[ . . . . ]

1

M_PI comes from <math.h>, the cstdlib include file.

2

Calling base class version on 'this'.


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

#include "shapes.h"
#include <QString>
#include <QDebug>

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.


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