#include <cstdio>
#include <vector>
enum eShapeType{
SPHERE,
CONE,
HULL,
CONVEX,
COMPLEX
};
class Shape{
public:
~Shape(void){};
virtual eShapeType type(void)const = 0;
};
class Convex: public Shape {
public:
virtual ~Convex(void){};
virtual void print(void)const = 0;
virtual eShapeType type(void)const{
return CONVEX;
}
};
class Sphere: public Convex{
public:
void print(void)const{
printf("This is a sphere!\n");
}
virtual eShapeType type(void)const{
return SPHERE;
}
};
class Cone: public Convex{
public:
void print(void)const{
printf("This is a cone!\n");
}
virtual eShapeType type(void)const{
return CONE;
}
};
void print_shape(const Shape& shape);
class Complex: public Shape{
public:
Complex(const std::vector<Shape*>& shapes):
shapes_(shapes)
{}
void print_shapes(void)const{
printf("This is a complex!\n");
for(auto shape: shapes_) print_shape(*shape);
}
virtual eShapeType type(void)const{
return COMPLEX;
}
const std::vector<Shape*>& get_shapes(void)const{
return shapes_;
}
private:
std::vector<Shape*> shapes_;
};
class Hull: public Convex{
public:
Hull(const std::vector<Convex*>& shapes):
shapes_(shapes)
{}
void print(void)const{
printf("This is a hull!\n");
for(const auto& shape: shapes_) shape->print();
}
virtual eShapeType type(void)const{
return HULL;
}
const std::vector<Convex*>& get_shapes(void)const{
return shapes_;
}
private:
std::vector<Convex*> shapes_;
};
void print_shape(const Shape& shape){
if(shape.type() < CONVEX) static_cast<const Convex&>(shape).print();
else static_cast<const Complex&>(shape).print_shapes();
}
int main(int argc, char* argv[]){
Sphere sphere;
Cone cone;
Hull hull(std::vector<Convex*>{
&sphere, &cone
});
Complex comp1(std::vector<Shape*>{
&sphere, &cone
});
Complex comp2(std::vector<Shape*>{
&sphere, &cone, &comp1
});
print_shape(hull);
print_shape(comp1);
print_shape(comp2);
return 0;
}