抽象类A继承自C类"通过" "中介" class B.如何声明虚函数?

时间:2018-04-23 22:11:47

标签: c++

我们说我有

struct Transformable {
    virtual void mirror()=0;
}

class Shape: public Transformable {
    Position position;
    Color color;
public:
    virtual void draw()=0; // 0. <-this, or
    virtual void draw(); // I. <-this, or
    void draw(); // II. <-this, or maybe
    // III. <-this?
}

class Circle {
    double radius;
public:
    void mirror();
}

(其中Transformable是抽象类A,Shape是&#34;中介&#34; B类,Circle是C.)

我应该从案例I-III中使用哪一个(在上面的评论中注明)? Shape有一个函数mirror()是没有意义的,所以我不想在那里写任何代码,选择选项0而不是III。 如果我想写代码,我会选择I over II。

如果我是对的,为什么?如果没有,为什么?

编辑:我需要用于异构集合的类Shape,并且我创建了一个Transformable类,使变换函数与所有内容分开。我也选择让它通过Shape,因为这样我就不必输入

AnyShape: public Transformable, public Shape

AnyShape: public Shape

2 个答案:

答案 0 :(得分:2)

通常,virtual关键字仅用于基类。您可以在所有派生类中省略它,但该方法仍然是虚拟的。您仍然可以使用它,但除了可读性之外,它不会添加太多内容。通常,在派生类中,关键字override是覆盖虚拟方法的首选,因为它会在编译时检查您实际覆盖了某些内容。所以你(通常)有:

class Base{
    virtual void method();
};

class Derived : public Base {
    void method() override; // still virtual
};

至于= 0,你可以在任何没有实现的地方添加它,或者你想强制派生的非抽象类(即你想在代码中实例化的类)来实现/覆盖某种方法。

请注意override仅在您使用C ++ 11及更高版本时可用。

答案 1 :(得分:0)

virtual void draw() = 0; 
virtual void draw(); 

是在Shape中声明函数的有效方法。

是否使用第一个或第二个的选择可以基于您期望Shape做什么以及您期望其子类型做什么(Circle是唯一的你已经展示了一个,但我估计会有更多。)

如果您希望Shape可以处理draw()的某些方面,但派生类必须拥有自己的实现,那么请使用第一个选项。实施Shape::draw()。派生类可以在其实现中使用Shape::draw()

如果您希望Shape能够处理某些类的draw()的所有方面,那么请使用第二个选项。在这种情况下,只有那些需要覆盖该函数的派生类才会覆盖它,而那些不需要的派生类可能会将其从实现中删除。

我的建议是选择第一个选项。如果某些派生类不需要执行任何操作,则可以调用Shape::draw()而不执行任何操作。 E.g。

class StrangeShape : public Shape
{
   public:
     void draw() override { Shape::draw(); }
};