应该是菜鸟问题...
我在现有类 A 中有现有代码,我想扩展它以覆盖现有方法 A::f()。
所以现在我想创建类 B 来覆盖 f(),因为我不想因为其他代码依赖于它而只更改 A::f()。
为此,我认为我需要将 A::f() 更改为虚拟方法。
我的问题是,除了允许动态调用方法(使用 B 的实现而不是 A 的实现)之外,将方法虚拟化还有其他含义吗?我是否违反了某种良好的编程习惯?这会影响任何其他尝试使用 A::f() 的代码吗?
请告诉我。
谢谢, jbu
编辑:我的问题更多的是将别人的方法虚拟化有什么问题吗?即使您没有更改其他人的实现,您仍然必须进入其他人的现有代码并对声明进行更改。
最佳答案
如果您在基类内部将函数设为虚函数,则从它派生的任何对象也将是虚函数。
一旦是虚拟的,如果你创建一个A
的实例,那么它仍然会调用A::f
。
如果创建 B 的实例并将其存储在 A*
类型的指针中。然后你调用 A*::->f
,然后它会调用 B
的 B::f
。
至于副作用,除了轻微(不明显)的性能损失外,可能不会有任何副作用。
还有一个非常小的副作用,可能有一个类 C 也派生自 A,它可能实现 C::f
,并且期望如果 A*::->f
被调用,那么它期望 A::f
被调用。但这不是很常见。
但更有可能的是,如果 C
存在,那么它根本不会实现 C::f
,在这种情况下一切都很好。
但是请注意,如果您使用的是已编译的库并且正在修改它的头文件,那么您期望的工作可能不会。您将需要重新编译头文件和源文件。
您可以考虑执行以下操作以避免副作用:
- 创建一个派生自
A
的类型A2
并使其成为f
虚拟类型- 使用
A2
类型的指针而不是A
- 从类型
A2
派生B
。 - 以这种方式,任何使用 A 的东西都可以保证以相同的方式工作
- 使用
根据您的需要,您还可以使用 has-a
关系而不是 is-a
。
关于C++ : implications of making a method virtual,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1821561/