C++ : implications of making a method virtual

标签 c++ virtual overriding implementation

应该是菜鸟问题...

我在现有类 A 中有现有代码,我想扩展它以覆盖现有方法 A::f()。

所以现在我想创建类 B 来覆盖 f(),因为我不想因为其他代码依赖于它而只更改 A::f()。

为此,我认为我需要将 A::f() 更改为虚拟方法。

我的问题是,除了允许动态调用方法(使用 B 的实现而不是 A 的实现)之外,将方法虚拟化还有其他含义吗?我是否违反了某种良好的编程习惯?这会影响任何其他尝试使用 A::f() 的代码吗?

请告诉我。

谢谢, jbu

编辑:我的问题更多的是将别人的方法虚拟化有什么问题吗?即使您没有更改其他人的实现,您仍然必须进入其他人的现有代码并对声明进行更改。

最佳答案

如果您在基类内部将函数设为虚函数,则从它派生的任何对象也将是虚函数。

一旦是虚拟的,如果你创建一个A的实例,那么它仍然会调用A::f

如果创建 B 的实例并将其存储在 A* 类型的指针中。然后你调用 A*::->f,然后它会调用 BB::f

至于副作用,除了轻微(不明显)的性能损失外,可能不会有任何副作用。

还有一个非常小的副作用,可能有一个类 C 也派生自 A,它可能实现 C::f,并且期望如果 A*::->f 被调用,那么它期望 A::f 被调用。但这不是很常见。

但更有可能的是,如果 C 存在,那么它根本不会实现 C::f,在这种情况下一切都很好。


但是请注意,如果您使用的是已编译的库并且正在修改它的头文件,那么您期望的工作可能不会。您将需要重新编译头文件和源文件。

您可以考虑执行以下操作以避免副作用:

  1. 创建一个派生自 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/

相关文章:

c++ - 将参数传递给自动转换为指针的函数

c++ - printf 的奇怪情况

c++ - 如何将对话框项的样式更改为测试模式中出现的样式?

c++ - 如果没有类重新实现 'virtual' 关键字是否可以优化掉?

c++ - 重写虚拟方法时,Cat 与 Animal 不协变

c++ - 有符号整数类型的最大值

c++ - 当我从下面的代码中删除关键字virtual时,它可以正常工作,否则会出错。单词 “virtual”在这里的意义是什么?

c++ - 虚函数+带基类指针的STL容器

PHP:覆盖子类的父类属性

c# - 为什么我们在对象模型项目中需要 GetHashCode() 函数?