#include <iostream>
using namespace std;
// 1 — виртуальное наследование;
// 0 — невиртуальное наследование.
#define USE_VIRTUAL_INHERITANCE 1
#if USE_VIRTUAL_INHERITANCE
#define FIGURE_BASE virtual public Figure
#else
#define FIGURE_BASE public Figure
#endif
// Базовый класс «Фигура»
class Figure {
public:
Figure() {
cout << "Figure: constructor" << endl;
}
virtual ~Figure() {
cout << "Figure: destructor" << endl;
}
virtual void draw() const = 0;
};
// Класс «Прямоугольник»
class Rectangle : FIGURE_BASE {
protected:
int width;
int height;
public:
Rectangle(int w = 24, int h = 8)
: width(w), height(h) {
cout << "Rectangle: constructor" << endl;
}
~Rectangle() override {
cout << "Rectangle: destructor" << endl;
}
void draw() const override {
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
if (y == 0 || y == height - 1 ||
x == 0 || x == width - 1) {
cout << '*';
} else {
cout << ' ';
}
}
cout << endl;
}
}
};
// Класс «Соприкасающиеся окружности»
class TouchingCircles : FIGURE_BASE {
protected:
int radius;
public:
explicit TouchingCircles(int r = 5)
: radius(r) {
cout << "TouchingCircles: constructor" << endl;
}
~TouchingCircles() override {
cout << "TouchingCircles: destructor" << endl;
}
void draw() const override {
const int r = radius;
const int offset = r;
for (int y = -r; y <= r; ++y) {
for (int x = -2 * r; x <= 2 * r; ++x) {
int d1 = (x + offset) * (x + offset) + y * y;
int d2 = (x - offset) * (x - offset) + y * y;
bool c1 = d1 >= r * r - r &&
d1 <= r * r + r;
bool c2 = d2 >= r * r - r &&
d2 <= r * r + r;
if (c1 || c2) {
cout << '*';
} else {
cout << ' ';
}
}
cout << endl;
}
}
};
// Составной класс с множественным наследованием
class Picture : public Rectangle, public TouchingCircles {
public:
Picture()
: Figure(),
Rectangle(24, 8),
TouchingCircles(5) {
cout << "Picture: constructor" << endl;
}
~Picture() override {
cout << "Picture: destructor" << endl;
}
void draw() const override {
cout << endl;
cout << "--- Прямоугольник ---" << endl;
Rectangle::draw();
cout << endl;
cout << "--- Соприкасающиеся окружности ---" << endl;
TouchingCircles::draw();
}
};
// Главная программа
int main() {
cout << "Создание объекта Picture:" << endl;
Figure* p = new Picture();
cout << endl;
cout << "Рисунок:" << endl;
p->draw();
cout << endl;
cout << "Удаление объекта Picture:" << endl;
delete p;
return 0;
}