Klassen in C++ II

Dieses Kapitel soll das Thema Klassen nicht vertiefen, sondern anhand eines Beispiels eine praktische Anwendung zeigen. Für unser Beispiel implementieren wir eine kleine Klassenhierarchie, welche 2 dimensionale Formen darstellen soll. Entsprechend heißt die Basisklasse hierfür Shape:
class shape
{
protected:
    int x,y;
    std::string farbe;// "rot"
public:
    shape();
    shape(int x, int y,const std::string& farbe);
    virtual ~shape();
    virtual double area() = 0;
    std::string Getfarbe()const;
    virtual int umfang();
};


Als Schnittstelle für unser Shape Hierarchie gibt es die Methoden area und umfang. Beide sind virtual, und können daher entsprechend von abgeleiteten konkreten Klassen implementiert werden, area ist pure virtual, muss also implementiert werden. Leider fehlen der shape Klasse ein Assignment Operator und der Copykonstruktor, diese kann der Leser selber implementieren, bzw. der Compiler. Der virtuelle Destruktor ist ebenfalls neu hier. Dieser sollte bei jeder Elternklasse vorhanden sein, um im Falle eines deletes den korrekten Destruktor aufrufen zu können.
Von Shape lassen sich nun diverse Klassen ableiten, welche 2d Formen darstellen, als Beispiel Rechteck und Dreieck:
class rectangle : public shape
{
    int width,height;
public:
    rectangle(const int width,const int height,int x, int y, const std::string& farbe);
    virtual ~rectangle();
    virtual double area();
    virtual int umfang();
};

class triangle : public shape
{
    int base,height;
public:
    triangle(const int& base,const int& height);
    virtual ~triangle();
    virtual double area();
    virtual int umfang();
};


Wie man sieht, spezialisieren sich beide Klassen auf eine konkrete Form.
In Benutzung könnte ein Beispiel für unsere Shape API nun so aussehen:
std::vector<shape*> shapes;//(1)
shapes.push_back(new triangle(10,15));//(2)
shapes.push_back(new rectangle(10,35,3,2,"orange"));
// viele weitere Shapes....
double shapearea = 0.0;//(3)
for(size_t i =0, s = shapes.size(); i < s; ++i)
    shapearea += shapes[i]->area();
//delete nicht vergessen! //(4)
for(size_t i =0, s = shapes.size(); i < s; ++i)
    delete shapes[i];
shapes.clear();


  1. Wir erstellen einen Vector von shape* Pointern, um einen Container für unsere Shapesammlung zu haben.
  2. Wir füllen unsere Shapesammlung mit den verschiedensten Shapes.
  3. Wir berechnen die Fläche aller Shapes.
  4. Wichtig ist, das die durch new angelegten Shapes auch wieder freigegeben werden! Hierbei kommt nun der virtuelle Destruktor ins Spiel, es wird also jeweils der Destruktor der konkreten Shape-Klasse aufgerufen, und nicht der von shape.