2017-06-19 65 views
3

如果某个类没有子类并且总是直接使用,是否有任何理由声明方法virtual是否有任何理由声明一个没有继承的虚拟方法?

例如:

class Foo { 
    public: 
    virtual void DoBar { 
     // Do something here. 
    } 
} 

我碰到这在一些代码,我正在读来了,找不到任何理由。

谢谢!

+0

如果你不使用'final',当然。例如,你几乎*拥有*来声明析构函数。你无法预测未来。不要使用final,这会锁定将来并显示你曾经想过。就像“虚拟”表明你曾经想过。 –

+0

@HansPassant使用**虚拟**并不一定表明你“想过它”。根据我的经验,我已经看到开发人员使用**虚拟**作为默认值,因为他们无法考虑这个问题。地狱,当我第一次学习Java时,它将这种方法推向了极致,所有方法都默认为虚拟的,甚至没有被标记为这样!它的目标似乎完全消除了思想。 –

回答

1

那么virtual关键字的本质就是继承关系。这是从CPP Ref的提取物: -

虚拟成员虚拟构件是一个成员函数,可以是 在派生类重新定义,同时通过引用保持其呼叫属性 。一个函数成为虚拟的语法是 先于其声明与虚拟关键字

所以恕我直言 - 俺们你的问题是没有 - 它没有任何意义 - 除非代码已经从最初的实施改变了 - 和相信我,发生了很多!

+0

该代码也可能违反YAGNI ...现在制作该虚拟,以便假设某个未来的子类可能会覆盖,如果它希望的话。 –

+0

接受这个答案,因为它对我的情况最有帮助 - 确认没有与函数内联或任何事情有关的奇怪原因。 – mfrankli

1

编写库代码时,记住未来的程序员可能想要扩展类并提供自己的行为,这很有用。例如,通常在GUI库中具有虚拟Paint()函数或虚拟鼠标处理函数。它们提供默认实现,但它们允许扩展的可能性。

1

如果这个类是从那里派生出来的话,那么它是有道理的。在决定程序的体系结构时,应该做出这些决定,并定义可以对接口做些什么。如果他们不希望这个来源于此,那么它不应该是虚拟的。如果他们确实希望它从那里派生出来,那么它应该是虚拟的(并且它也应该使析构器变为虚拟的)。

+0

你说“如果他们不想让它从那里派生出来,它不应该是虚拟的”,但是一个非虚拟方法不会阻止派生类重写它,它只是意味着新方法不能通过基类来使用指针。如有必要,派生类可以调用基类方法。 – Tony