多态性的良好实践

Shi*_*bli 1 c++ polymorphism pointers

假设a Domain存储指针Shape.确切的形状(TriangleRectangle)在编译时是未知的,并且在读取输入后将清楚.在运行时,我可能需要访问派生结构的变量,但这是不可能的,因为指针指向基础结构.我发现了另一个解决方案是做"接通型",而是在回答指出,它不鼓励在这里.他也说过

当您使用多态时,您不需要关心基类引用/指针背后的内容.

那么在这种情况下我会关心,所以听起来我不应该使用多态.我想我在下面做的是一个糟糕的设计,但那么解决这个问题的好设计是什么?

struct Shape
{
    int common_variable;
};

struct Triangle: Shape
{
    int triangle_specific_variable;
};

struct Rectangle: Shape
{
    int rectangle_specific_variable;
};

struct Domain
{
    Shape* shape;
};

int main()
{
    Domain domain;
    //domain.shape = new Triangle(); // depends on input.
    //domain.shape = new Rectangle(); // depends on input.

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*phe 6

你的问题清楚地表明需要多态性,因为你想使用三角形,重新排列等等,你知道所有这些都是形状.

为什么不建议使用交换机访问特定数据?

因为这与多态设计恰恰相反.而不是使用形状,绘制它们,计算它们的面积等...你总是需要知道形状的类型和代码特定的行为.

想象一下,你已经完成了你的代码,然后你发现你也想要正方形和圆形:维持这个是多么噩梦.

怎么解决这个?

您必须从具体类中抽象出来,并定义可以对常规形状执行的一般操作.然后将这些操作定义为虚函数,并在使用Domain的代码中,只需调用虚函数.

要进一步进行分类,可以使用从流中返回形状的工厂方法,而不是从类中创建对象.

例:

class Shape
{
public: 
    virtual void scale(double scale_factor)=0; 
    virtual void rotate(double angle)=0; 
    virtual void draw(window w)=0; 
    virtual Shape* clone()=0; 
    virtual ~Shape() {}
}; 

class Triangle: public Shape
{
    Point A, B, C; 
public: 
    Triangle (Point a,Point b, Point c) : A(a), B(b), C(c) { }
    void scale(double scale_factor) override; 
    void rotate(double angle) override; 
    void draw(window w) override; 
    Shape* clone() { return new Triangle(*this); }      
};

...

int main()
{
    Domain domain, domain2;
    Window wnd = CreateWindow(...);  // depends on your GUI library
    Point a,b,c; 
    cin >> a >> b >> c; 
    domain.shape = new Triangle(a,b,c); 

    // Once the object is constructed no need to know the details of the shape here
    domain.shape->rotate(45); 
    domain2.shape = domain.shape->clone(); 
    domain.shape->draw(wnd); 
    ...
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

请注意,使用智能指针比使用原始指针更安全;