分享

为什么C++中virtual要翻译为虚函数?

 半佛肉夹馍 2023-10-20 发布于河南

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

听说过“虚指”吗?

一片孤城万仞山——据说七尺为仞,万仞少说也得两万米,地球上有这种山吗?

飞流直下三千尺——落差高达1km的瀑布,谁能到庐山找一条出来?

白发三千丈——三千丈的头发得多少公斤重?9km长了,这一般卡车都拖不动吧?换火车头!

这种修辞法就叫“虚指”。万仞山、三千尺、三千丈,以及屡次三番的三、四处漂泊的四,这些都是虚指;意思是形容高、长、多,等等。具体的数字没有意义,可能比实际上多(万仞)、也可能比实际上少(四处漂泊实际上可能有九个城市,实际来源大概是四'方’;三军经常也不是什么海陆空或者中军左军右军,而是麾下所有部队——不然你把预备队算什么?抄后路的奇兵又往哪放?)。


有了这个基础知识,我们再来看看C++ virtual function究竟是什么。

class A {
public:
virtual int a1();
int a2();
}

class B: public A {
public:
virtual int a1();
int b2();
}

虚函数a1和非虚函数a2有什么区别?

很简单,我们可以用一个指向类型A的指针索引A或B的对象;当通过这个指针调用对象的方法时,a1和a2表现不同。

对于a1,对基类对象,调用的是A::a1;对派生类对象呢,调用的是B::a1。

而对a2,任何时候调用的都是A::a2——你在B中改写a2,那叫隐藏,以后通过B类型的指针默认就访问不到A::a2了,只能访问B::a2(除非刻意指定);反之,通过A类型的指针也只能访问到A::a2。总之指针类型不同实际访问的东西就不一样。这会造成很多令人迷惑的问题,因此才有了一个约定:没有说明为virtual的函数就不要改写,棘手问题太多。

你看,a2这个函数是“实”的,在编译时就知道你要调用哪个,不存在任何含糊/灵活之处。

而a1呢,只有在运行时才会根据对象的不同选择正确的版本,和指针类型无关。

假如对类Person,run方法是virtual;那么小孩的run和老人和残疾人的run就各有不同。

换句话说,调用者只关心我发了个命令叫他们run他们就要run,但怎么run用什么run(拐杖?轮椅?),他是不管的。

忽略细节,只关注本质,这不正是“虚指”吗?

具体多高多远不关心,反正随便写个数字,你知道高/远就行了。

同样的,具体执行的是哪个run、如何run不关心,能安排给某个函数就行了。

还能有比这个更信达雅的翻译吗?

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多