我读到了关于这个问题的不同意见。假设我有一个带有一堆纯虚方法的接口类。我在实现接口的类中实现这些方法,并且我不希望从实现中派生。
是否需要将实现中的方法也声明为虚拟方法?如果是,为什么?
否 - 在基类中声明为 virtual 的每个函数方法在所有派生类中都将是 virtual。
但是良好的编码实践告诉我们将这些方法声明为虚拟的。
virtual
在派生类重写声明中是可选的,但为了清楚起见,我个人将其包含在内。
真正的需要 - 不。一旦某个方法在基类中被声明为虚拟方法,它对于所有派生类都保持虚拟状态。但最好知道哪个方法是虚拟的,哪个不是虚拟的,而不是在基类中检查它。此外,在大多数情况下,您无法确定您的代码是否会派生(例如,如果您正在为某些公司开发某些软件)。正如我所说,这不是问题,因为一旦声明为虚拟,它就保持虚拟,但以防万一..(:
无需将它们标记为虚拟。
我首先要指出的是,virtual 向读者宣传您希望派生类重写 virtual 来执行一些有用的操作。如果您正在实现 virtual 来做某事,那么 virtual 方法可能与您的类的类型无关:在这种情况下将其标记为 virtual 是愚蠢的。考虑:
class CommsObject {
virtual OnConnect();
virtual OnRawBytesIn();
};
class XMLStream : public CommsObject {
virtual OnConnect();
OnRawBytesIn();
virtual OnXMLData();
};
在该示例中,OnConnect 在两个类中都被记录为虚拟,因为后代总是想知道这是有道理的。 OnRawBytesIn 从 XMLStream“导出”没有意义,因为它使用它来处理原始字节并生成解析的数据 - 它通过 OnXMLData() 通知。
完成所有这些后,我认为第三类的维护者在查看 XMLStream 时可能会认为创建自己的 OnRawBytes 函数并期望它作为正常的重载函数工作是“安全的” - 即基类将调用内部正确的类,而外部类将屏蔽内部的 OnRawBytes。
因此,省略 virtual 向类的使用者隐藏了重要的细节,并使代码以意想不到的方式运行。
所以我又绕了一圈:不要试图用它来暗示函数的预期目的 - 一定要用它来暗示函数的行为:一致地将函数标记为虚拟,这样下游程序员就必须读取更少的文件了解函数被重写时的行为方式。
一旦“虚拟”,直到最后一个孩子都是虚拟的。 Afaik,这就是 c++ 的功能。
如果您从未从类派生,那么将其方法设为虚拟是没有意义的。