何时将 C++ 中的函数标记为虚拟函数?
由于方法静态绑定的 C++ 特性,这会影响多态调用.
Because of C++ nature of static-binding for methods, this affects the polymorphic calls.
来自维基百科:
虽然这种调度机制涉及的开销很低,但它对于该语言的某些应用领域可能仍然很重要旨在针对.出于这个原因,Bjarne StroustrupC++ 的设计者,选择使动态调度可选并且非默认.只有使用 virtual 关键字声明的函数才会基于对象的运行时类型调度;其他功能将根据对象的静态类型进行分派.
Although the overhead involved in this dispatch mechanism is low, it may still be significant for some application areas that the language was designed to target. For this reason, Bjarne Stroustrup, the designer of C++, elected to make dynamic dispatch optional and non-default. Only functions declared with the virtual keyword will be dispatched based on the runtime type of the object; other functions will be dispatched based on the object's static type.
所以代码:
Polygon* p = new Triangle;
p->area();
如果 area()
是 Parent 类中的 non-virtual
函数,并且在 Child 类中被 overridden
,则上面的代码将调用开发人员可能不期望的 Parent 的类方法
.(感谢我介绍的静态绑定)
provided that area()
is a non-virtual
function in Parent class that is overridden
in the Child class, the code above will call the Parent's class method
which might not be expected by the developer. (thanks to the static-binding I've introduced)
那么,如果我想编写一个供其他人使用的类(例如库),我是否应该将我的所有函数都设置为虚拟的,以便之前的代码能够按预期运行?p>
So, If I want to write a class to be used by others (e.g library), should I make all my functions to be virtual for the such previous code to run as expected?
推荐答案
简单的答案是,如果您打算重写类的函数以实现运行时多态性,您应该将它们标记为 virtual
,而不是如果你不打算这样做.
The simple answer is if you intend functions of your class to be overridden for runtime polymorphism you should mark them as virtual
, and not if you don't intend so.
不要仅仅因为你觉得它赋予了额外的灵活性而将你的函数标记为virtual
,而是想想你的设计和公开接口的目的.例如:如果您的类不是为继承而设计的,那么将您的成员函数设为虚拟会产生误导.一个很好的例子是标准库容器,它不应该被继承,因此它们没有虚拟析构函数.
Don't mark your functions virtual
just because you feel it imparts additional flexibility, rather think of your design and purpose of exposing an interface. For ex: If your class is not designed to be inherited then making your member functions virtual will be misleading. A good example of this is Standard Library containers,which are not meant to be inherited and hence they do not have virtual destructors.
没有理由不将所有成员函数标记为虚拟,引用一些性能损失,非 POD 类类型等等,但如果你真的打算有意 对于运行时覆盖而言,这就是它的目的以及所谓的缺陷.
There are n no of reasons why not to mark all your member functions virtual, to quote some performance penalties, non-POD class type and so on, but if you really intent that your class is intended for run time overidding then that is the purpose of it and its about and over the so-called deficiencies.
相关文章