如何在从不同基类派生的类的构造函数中调用不同的派生类

时间:2014-10-28 00:43:10

标签: c++ factory strategy-pattern decoupling

在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 *“的值不能被赋予类型的实体“矩形”。错误很明显,为什么这段代码不起作用。

有人知道如何让代码在这里做我正在尝试做的事情吗?

从设计角度来看,我认识到问题的一部分是派生类最终被耦合,所以也许有更好的方法来尝试将计算器类与形状类分离。但是我想在我的实现中至少尝试一下这种方法,为此我需要编译代码。

1 个答案:

答案 0 :(得分:0)

我不完全确定你在这里想要实现的目标,但我认为更常用的方法是:

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';
}