В C ++ у меня есть два отдельных базовых класса, каждый из которых имеет несколько связанных производных классов. Вот пример того, что я хотел бы сделать:
Сначала определите набор классов, например:
class Shape
{
public:
double area;
double diameter;
};
class Rectangle : public Shape
{
public:
double width;
double height;
};
class Circle : public Shape
{
public:
double radius;
};
Второй набор классов относится к операциям, выполняемым с этим первым набором классов, что-то вроде этого:
class Calculator
{
public:
static Calculator *create_calculator(shape *shape,const char *shape_type); // the factory
virtual void calculate()=0; // the actual calculation
};class area_circles : public Calculator
{
class circles *circle;
public
area_circles(circles *circle)
{
this->circle = circle;
}
void calculate()
{
this->area = PI*pow(circle->radius,2);
}
}class area_rectangles : public Calculator
{
class rectangles *rectangle;
public
area_rectangles(rectangles *rectangle)
{
this->rectangle = rectangle;
}
double calculate()
{
this->area = rectangle->height * rectangle->width;
}
}
Calculator *Calculator::create_calculator(shape *shape, const char *shape_type)
{
if (shape_type=="circle")
return new area_circles(shape);
if (shape_type=="rectangle")
return new area_rectangles(shape);
}
Тогда идея заключается в том, чтобы вызвать все это, используя что-то вроде:
rectangles *my_rectangle;
Calculator *area_calculator;
area_calculator = area_calculator->create_calculator(my_rectangle, "rectangle");
area_calculator->calculate();
Однако это не компилируется, и я получаю сообщение об ошибке (весьма разумно), указывающее, что у класса Shape нет члена «width», и что «значению типа» shape * «нельзя присвоить объект типа» прямоугольники » Ошибка довольно ясна, почему этот код не работает.
Кто-нибудь знает, как получить код здесь, чтобы делать то, что я пытаюсь сделать?
С точки зрения дизайна, я понимаю, что отчасти проблема заключается в том, что производные классы в конечном итоге соединяются, поэтому, возможно, есть лучший способ отделить класс калькулятора от класса формы. Но я хотел бы, по крайней мере, на некоторое время опробовать этот подход в моей реализации, и для этого мне нужен код для компиляции.
Я не совсем уверен, чего вы здесь добиваетесь, но я думаю, что более обычный подход к этому примерно такой:
class Shape
{
public:
virtual ~Shape() {}
// concrete classes must implement this function
virtual double get_area() const = 0;
};
class Circle
: public Shape
{
double diameter;
public:
Circle(double diameter): diameter(diameter) {}
virtual double get_area() const
{
return M_PI * diameter * diameter / 4;
}
};
class Rectangle
: public Shape
{
double width;
double height;
public:
Rectangle(double width, double height): width(width), height(height) {}
virtual double get_area() const
{
return width * height;
}
};
int main()
{
Circle c(2);
Rectangle r(20, 40);
// use Shape references (or pointers) to invoke polymorphic behaviour
Shape& cs = c;
Shape& rs = r;
std::cout << "Area of circle : " << cs.get_area() << '\n';
std::cout << "Area of rectangle: " << rs.get_area() << '\n';
}