【发布时间】:2011-04-30 18:47:15
【问题描述】:
我读到了关于这个问题的不同意见。假设我有一个带有一堆纯虚方法的接口类。我在实现接口的类中实现这些方法,我不希望从实现派生。
是否需要将实现中的方法也声明为虚拟的?如果是,为什么?
【问题讨论】:
标签: c++ interface methods virtual
我读到了关于这个问题的不同意见。假设我有一个带有一堆纯虚方法的接口类。我在实现接口的类中实现这些方法,我不希望从实现派生。
是否需要将实现中的方法也声明为虚拟的?如果是,为什么?
【问题讨论】:
标签: c++ interface methods 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 对类的使用者隐藏了重要的细节,并使代码以意想不到的方式运行。
所以我绕了一圈:不要试图用它来暗示函数的预期用途 - 一定要用它来暗示函数的行为:将函数标记为虚拟一致,以便下游程序员必须阅读更少的文件来了解函数在被覆盖时的行为方式。
【讨论】:
不,它不是必需的,并且它不能防止任何编码错误,尽管许多编码人员更愿意使用它。
一旦 C++0x 成为主流,您就可以改用 override 说明符。
【讨论】:
一旦“虚拟”,它一直是虚拟的,一直到最后一个孩子。 Afaik,这就是 c++ 的特性。
【讨论】:
如果您从不从类派生,那么将其方法设为虚拟就没有意义。
【讨论】: