| Bruce Eckel's Thinking in C++, 2nd Ed | Contents | Prev | Next |
Show simpler version of virtual constructor scheme, letting the user create the object with new. Probably make constructor for objects private and use a maker function to force all objects on the heap.
//: C:ShapeV.cpp
// "Virtual constructors"
// Used in a simple "Shape" framework
#include <iostream>
#include <vector>
#include "../purge.h"
using namespace std;
class Shape {
Shape* S;
// Prevent copy-construction & operator=
Shape(Shape&);
Shape operator=(Shape&);
protected:
Shape() { S = 0; };
public:
enum type { tCircle, tSquare, tTriangle };
Shape(type); // "Virtual" constructor
virtual void draw() { S->draw(); }
virtual ~Shape() {
cout << "~Shape\n";
delete S;
}
};
class Circle : public Shape {
Circle(Circle&);
Circle operator=(Circle&);
public:
Circle() {}
void draw() { cout << "Circle::draw\n"; }
~Circle() { cout << "~Circle\n"; }
};
class Square : public Shape {
Square(Square&);
Square operator=(Square&);
public:
Square() {}
void draw() { cout << "Square::draw\n"; }
~Square() { cout << "~Square\n"; }
};
class Triangle : public Shape {
Triangle(Triangle&);
Triangle operator=(Triangle&);
public:
Triangle() {}
void draw() { cout << "Triangle::draw\n"; }
~Triangle() { cout << "~Triangle\n"; }
};
Shape::Shape(type t) {
switch(t) {
case tCircle: S = new Circle; break;
case tSquare: S = new Square; break;
case tTriangle: S = new Triangle; break;
}
draw(); // Virtual call in the constructor
}
int main() {
vector<Shape*> shapes;
cout << "virtual constructor calls:" << endl;
shapes.push_back(new Shape(Shape::tCircle));
shapes.push_back(new Shape(Shape::tSquare));
shapes.push_back(new Shape(Shape::tTriangle));
cout << "virtual function calls:" << endl;
for(int i = 0; i < shapes.size(); i++)
shapes[i]->draw();
Shape c(Shape::tCircle); // Can create on stack
purge(shapes);
} ///:~