1
+ #include < iostream>
2
+ #include < cmath>
3
+ #include < vector>
4
+
5
+ class Shape
6
+ {
7
+ public:
8
+ enum class Type
9
+ {
10
+ RECTANGLE,
11
+ TRIANGLE,
12
+ CIRCLE
13
+ };
14
+
15
+ Shape () = default ;
16
+
17
+ virtual double getArea () const = 0;
18
+ virtual Shape *clone () const = 0;
19
+ virtual Type getType () const = 0;
20
+
21
+ virtual ~Shape () = default ;
22
+ };
23
+
24
+ class Rectangle : public Shape
25
+ {
26
+ public:
27
+ Rectangle () = default ;
28
+ Rectangle (const double &width, const double &height) : width(width), height(height) {}
29
+
30
+ double getWidth () const
31
+ {
32
+ return this ->width ;
33
+ }
34
+
35
+ double getHeight () const
36
+ {
37
+ return this ->height ;
38
+ }
39
+ double getArea () const override
40
+ {
41
+ return this ->width * height;
42
+ }
43
+
44
+ Shape *clone () const override
45
+ {
46
+ return new Rectangle (*this );
47
+ }
48
+
49
+ Type getType () const override
50
+ {
51
+ return Type::RECTANGLE;
52
+ }
53
+
54
+ private:
55
+ double width;
56
+ double height;
57
+ };
58
+
59
+ class Triangle : public Shape
60
+ {
61
+ public:
62
+ Triangle () = default ;
63
+ Triangle (const double &a, const double &b, const double &c) : a(a), b(b), c(c) {}
64
+
65
+ double getA () const
66
+ {
67
+ return this ->a ;
68
+ }
69
+
70
+ double getB () const
71
+ {
72
+ return this ->b ;
73
+ }
74
+
75
+ double getC () const
76
+ {
77
+ return this ->c ;
78
+ }
79
+
80
+ double getArea () const override
81
+ {
82
+ double p = (a + b + c) / 2 ;
83
+ return sqrt (p * (p - a) * (p - b) * (p - c));
84
+ }
85
+
86
+ Shape *clone () const override
87
+ {
88
+ return new Triangle (*this );
89
+ }
90
+
91
+ Type getType () const override
92
+ {
93
+ return Type::TRIANGLE;
94
+ }
95
+
96
+ private:
97
+ double a;
98
+ double b;
99
+ double c;
100
+ };
101
+
102
+ class Circle : public Shape
103
+ {
104
+ public:
105
+ const double PI = 3.14 ;
106
+ Circle (const double &radius = 0 ) : radius(radius) {}
107
+
108
+ double getRadius () const
109
+ {
110
+ return this ->radius ;
111
+ }
112
+ double getArea () const override
113
+ {
114
+ return PI * radius * radius;
115
+ }
116
+
117
+ Shape *clone () const override
118
+ {
119
+ return new Circle (*this );
120
+ }
121
+
122
+ Type getType () const override
123
+ {
124
+ return Type::CIRCLE;
125
+ }
126
+
127
+ private:
128
+ double radius;
129
+ };
130
+
131
+ class Shapes
132
+ {
133
+ private:
134
+ std::vector<Shape *> shapes;
135
+
136
+ public:
137
+ Shapes () = default ;
138
+
139
+ void add (const Shape *const shape)
140
+ {
141
+ this ->shapes .push_back (shape->clone ());
142
+ }
143
+
144
+ Shape *operator [](const int index) const
145
+ {
146
+ return this ->shapes [index ];
147
+ }
148
+
149
+ unsigned size () const
150
+ {
151
+ return this ->shapes .size ();
152
+ }
153
+
154
+ ~Shapes ()
155
+ {
156
+ for (auto *shape : shapes)
157
+ {
158
+ delete shape;
159
+ }
160
+ }
161
+ };
162
+
163
+ int main ()
164
+ {
165
+ Shapes shapes;
166
+
167
+ Rectangle rectangle (3 , 5 );
168
+ shapes.add (&rectangle);
169
+
170
+ Triangle triangle (3 , 4 , 5 );
171
+ shapes.add (&triangle);
172
+
173
+ Circle circle (5 );
174
+ shapes.add (&circle);
175
+
176
+ for (int i = 0 ; i < shapes.size (); i++)
177
+ {
178
+ // bad practise, this is not a polymorphic code
179
+ if (shapes[i]->getType () == Shape::Type::RECTANGLE)
180
+ {
181
+ std::cout << " This rectangle's area is: " ;
182
+ }
183
+ else if (shapes[i]->getType () == Shape::Type::TRIANGLE)
184
+ {
185
+ std::cout << " This triangle's area is: " ;
186
+
187
+ Triangle *asTriangle = (Triangle *)shapes[i];
188
+ std::cout << asTriangle->getA ();
189
+ }
190
+ else if (shapes[i]->getType () == Shape::Type::CIRCLE)
191
+ {
192
+ std::cout << " This circle's area is: " ;
193
+ }
194
+ std::cout << shapes[i]->getArea () << std::endl;
195
+ }
196
+ }
0 commit comments