我们说我有
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
答案 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(); }
};