https://mp.weixin.qq.com/s?__biz=MzAxNzYzMTU0Ng==&mid=2651289202&idx=1&sn=431ffd1fae4823366a50b68aed2838d4&chksm=80114627b766cf31f72018ef5f1fe29591e9f6f4bd72018e7aea849342ca6f0a271fb38465ae#rd

打开链接看。转载文章,注明出处

                <p>学习C++的多态性,你必然听过虚函数的概念,你必然知道有关她的种种语法,但你未必了解她为什么要那样做,未必了解她种种行为背后的所思所想。深知你不想在流于表面语法上的蜻蜓点水似是而非,今天我们就一起来揭开挡在你和虚函数(女神)之间的这一层窗户纸。</p><p style="white-space: normal;"><br></p><p style="white-space: normal;text-align: center;"><img class="" data-ratio="0.040690505548705305" data-src="http://mmbiz.qpic.cn/mmbiz_png/d0YYOX6ZlbwxEuFWMbayZLMTA3E4icqQ0LTQYboqGxvVCAF7yj9TOJjRgYTJjc8eichlRgco5icXaofHEwThf73MQ/0?wx_fmt=png" data-type="png" data-w="811" title="分割线" style="display: inline; width: 547px !important; height: auto !important; visibility: visible !important;" _width="547px" src="http://mmbiz.qpic.cn/mmbiz_png/d0YYOX6ZlbwxEuFWMbayZLMTA3E4icqQ0LTQYboqGxvVCAF7yj9TOJjRgYTJjc8eichlRgco5icXaofHEwThf73MQ/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" crossorigin="anonymous" data-fail="0"></p><p style="white-space: normal;text-align: center;"><br></p><p style="white-space: normal;">首先,我们要搞清楚女神的所作所为,即语法规范。然后再去探究她背后的逻辑道理。她的语法说来也不复杂,概括起来就这么几条:</p><p style="white-space: normal;"><br></p><ol class="list-paddingleft-2" style="list-style-type: decimal;"><li><p style="white-space: normal;">在类成员方法的声明(不是定义)语句前面加个单词:<span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>virtual</strong></span>,她就会摇身一变成为虚函数。</p></li><li><p style="white-space: normal;">在虚函数的声明语句末尾中加个 <strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">=0</span></strong> ,她就会摇身一变成为纯虚函数。</p></li><li><p style="white-space: normal;">子类可以重新定义基类的虚函数,我们把这个行为称之为<strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">复写</span></strong>(<span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>override</strong></span>)。</p></li><li><p style="white-space: normal;">不管是虚函数还是纯虚函数,<strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">基类都可以为提供他们的实现</span></strong>(<span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>implementation</strong></span>),如果有的话子类可以调用基类的这些实现。</p></li><li><p style="white-space: normal;">子类可<strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">自主选择</span></strong>是否要提供一份属于自己的个性化虚函数实现。</p></li><li><p style="white-space: normal;">子类<strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">必须提供</span></strong>一份属于自己的个性化纯虚函数实现。</p><p style="white-space: normal;"><br></p></li></ol><section class="" data-tools="135编辑器" data-id="90142" style="border-width: 0px; border-style: none; border-color: initial; box-sizing: border-box; --darkreader-inline-border-top: initial; --darkreader-inline-border-right: initial; --darkreader-inline-border-bottom: initial; --darkreader-inline-border-left: initial;" data-darkreader-inline-border-top="" data-darkreader-inline-border-right="" data-darkreader-inline-border-bottom="" data-darkreader-inline-border-left=""><section style="text-align:center;"><section style="display:inline-block;"><img class=" __bg_gif" data-ratio="0.6470588235294118" data-src="http://mmbiz.qpic.cn/mmbiz_gif/d0YYOX6Zlby3pIrMZzOlNLBFgYEWJI3P7oPYfGhH71NFibcIASiadaicc9qC3RlIwvibOaTxaAczEGYC5fND4qZibaQ/0?wx_fmt=gif" data-type="gif" data-w="34" style="display: inline; width: 34px !important; height: auto !important; visibility: visible !important;" title="音符动态简约分割线" _width="34px" src="http://mmbiz.qpic.cn/mmbiz_gif/d0YYOX6Zlby3pIrMZzOlNLBFgYEWJI3P7oPYfGhH71NFibcIASiadaicc9qC3RlIwvibOaTxaAczEGYC5fND4qZibaQ/0?wx_fmt=gif&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" data-order="0" data-fail="0"></section></section></section><p><br></p><p>语法都列出来了,背后的逻辑含义是什么呢?我们用一个生动的例子来说明,虚函数是如何实现多态性的。</p><p><br></p><p>假设我们要设计关于飞行器的类,并且提供类似加油、飞行的实现代码,考虑具体情况,飞行器多种多样,有民航客机、歼击机、轰炸机、直升机、热气球、火箭甚至窜天猴、孔明灯、纸飞机!</p><p>假设我们有一位牛得一比的飞行员,他能给各式各样的飞行器加充不同的燃料,也能驾驶各式各样的飞行器。下面我们来看看这些类可以怎么设计。</p><p style="text-align: center;"><img data-s="300,640" data-type="jpeg" data-src="https://mmbiz.qpic.cn/mmbiz_jpg/d0YYOX6Zlby3pIrMZzOlNLBFgYEWJI3PT70rvCkl3ZpWOwS6SAQTj2G6leoucU40ly2BI7f7kUBlSXvFMQkMxg/0?wx_fmt=jpeg" data-copyright="0" style="width: 164px !important; height: auto !important; visibility: visible !important;" class="" data-ratio="1.397887323943662" data-w="284" _width="164px" src="https://mmbiz.qpic.cn/mmbiz_jpg/d0YYOX6Zlby3pIrMZzOlNLBFgYEWJI3PT70rvCkl3ZpWOwS6SAQTj2G6leoucU40ly2BI7f7kUBlSXvFMQkMxg/640?wx_fmt=jpeg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" crossorigin="anonymous" data-fail="0"></p><p>首先,飞行器。由于我们假设所有的飞行器都有两种行为:<span style="color: rgb(217, 33, 66); --darkreader-inline-color:#d86677;" data-darkreader-inline-color=""><strong>加油</strong><span style="color: rgb(0, 0, 0); --darkreader-inline-color:#e9e3d5;" data-darkreader-inline-color="">和</span><strong>飞行</strong></span>。因此我们可以将这两种行为抽象到一个基类中,并由它来派生具体的某款飞行器。</p><p><br></p><p><em><span style="font-size: 14px; color: rgb(178, 178, 178); --darkreader-inline-color:#c3b49e;" data-darkreader-inline-color="">这是一个描述飞行器的基类,提供了两个基本的功能:加油和飞行</span></em></p><blockquote><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">class aircraft</span></strong></p><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">{</span></strong></p><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">&nbsp; &nbsp; void <span style="color: rgb(217, 33, 66); --darkreader-inline-color:#d86677;" data-darkreader-inline-color="">refuel</span>(); </span></strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">// 加燃油,普通虚函数</span></p><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">&nbsp; &nbsp; void <span style="color: rgb(217, 33, 66); --darkreader-inline-color:#d86677;" data-darkreader-inline-color="">fly</span>()=0; </span></strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">&nbsp;// 飞行,纯虚函数</span></p><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">};</span></strong></p></blockquote><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><br></span></strong></p><p style="line-height: normal;"><em><span style="font-size: 14px; color: rgb(178, 178, 178); --darkreader-inline-color:#c3b49e;" data-darkreader-inline-color="">这是一个普通虚函数,意味着基类希望子类提供自己的个性化实现代码,但基类同时也提供一个缺省的虚函数实现版本,在子类不复写该虚函数的情况下作为备选方案</span></em></p><blockquote><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">void aircraft::<span style="color: rgb(217, 33, 66); --darkreader-inline-color:#d86677;" data-darkreader-inline-color="">refuel</span>()</span></strong></p><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">{</span></strong></p><p style="line-height: normal;"><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">&nbsp; &nbsp; // 加充通用型燃油</span></p><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">}</span></strong></p></blockquote><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><br></span></strong></p><p style="line-height: normal;"><em><span style="font-size: 14px; color: rgb(178, 178, 178); --darkreader-inline-color:#c3b49e;" data-darkreader-inline-color="">这是一个纯虚函数,意味着基类强制子类必须提供自己的个性化版本,否则编译将失败。但让人惊奇的是,C++仍然保留了基类提供该纯虚函数代码实现的权利,这也许是给千变万化的实际情况留下后路</span></em></p><blockquote><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">void aircraft::<span style="color: rgb(217, 33, 66); --darkreader-inline-color:#d86677;" data-darkreader-inline-color="">fly</span>()</span></strong></p><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">{</span></strong></p><p style="line-height: normal;"><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">&nbsp; &nbsp; // 一种不应该被使用的缺省飞行方案</span></p><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">}</span></strong></p></blockquote><p><br></p><p>有了基类aircraft,我们就可以潇洒地派生出各式各样的飞行器了,比如<strong><span style="color: rgb(123, 12, 0); --darkreader-inline-color:#f19385;" data-darkreader-inline-color="">轰炸机</span></strong>和<strong><span style="color: rgb(123, 12, 0); --darkreader-inline-color:#f19385;" data-darkreader-inline-color="">直升机</span></strong>:<br></p><p style="text-align: center;"><img data-s="300,640" data-type="png" data-src="https://mmbiz.qpic.cn/mmbiz_png/d0YYOX6Zlby3pIrMZzOlNLBFgYEWJI3PfMEezwpiaooicVBfbqUtZqmHjibqIJHwU7s6qP8Yj1mGD0kpq4OOS5ZiaA/0?wx_fmt=png" data-copyright="0" style="width: 220px !important; height: auto !important; visibility: visible !important;" class="" data-ratio="0.49290060851926976" data-w="493" _width="220px" src="https://mmbiz.qpic.cn/mmbiz_png/d0YYOX6Zlby3pIrMZzOlNLBFgYEWJI3PfMEezwpiaooicVBfbqUtZqmHjibqIJHwU7s6qP8Yj1mGD0kpq4OOS5ZiaA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" crossorigin="anonymous" data-fail="0"><img data-s="300,640" data-type="jpeg" data-src="https://mmbiz.qpic.cn/mmbiz_jpg/d0YYOX6Zlby3pIrMZzOlNLBFgYEWJI3PEyKgERCNSia86eKWflCtaFxCFcqtSTSibHHSicl90kRs9SI68XkFxTn5w/0?wx_fmt=jpeg" data-copyright="0" class="" data-ratio="0.3764705882352941" data-w="425" style="width: 251px !important; height: auto !important; visibility: visible !important;" _width="251px" src="https://mmbiz.qpic.cn/mmbiz_jpg/d0YYOX6Zlby3pIrMZzOlNLBFgYEWJI3PEyKgERCNSia86eKWflCtaFxCFcqtSTSibHHSicl90kRs9SI68XkFxTn5w/640?wx_fmt=jpeg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" crossorigin="anonymous" data-fail="0"></p><p><em><span style="font-size: 14px; color: rgb(178, 178, 178); --darkreader-inline-color:#c3b49e;" data-darkreader-inline-color="">轰炸机类定义,复写了加油和飞行</span></em></p><blockquote><p style="line-height: normal;"><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>class&nbsp;</strong></span><strong><span style="color: rgb(123, 12, 0); --darkreader-inline-color:#f19385;" data-darkreader-inline-color="">bomber</span></strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong> : public aircraft</strong></span></p><p style="line-height: normal;"><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>{</strong></span></p><p style="line-height: normal;"><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>&nbsp; &nbsp; void <span style="color: rgb(216, 79, 169); --darkreader-inline-color:#d270ac;" data-darkreader-inline-color="">refuel</span>(){}</strong> // 加充轰炸机的特殊燃油!</span></p><p style="line-height: normal;"><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>&nbsp; &nbsp; void</strong></span> <span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong><span style="color: rgb(216, 79, 169); --darkreader-inline-color:#d270ac;" data-darkreader-inline-color="">fly</span></strong><strong>(){}</strong> // 轰炸机实弹飞行!</span></p><p style="line-height: normal;"><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>};</strong></span></p></blockquote><p><br></p><p><em><span style="font-size: 14px; color: rgb(178, 178, 178); --darkreader-inline-color:#c3b49e;" data-darkreader-inline-color="">直升机类定义,复写了飞行代码,但没有复写加油</span></em></p><blockquote><p style="line-height: normal;"><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>class&nbsp;</strong></span><strong><span style="color: rgb(123, 12, 0); --darkreader-inline-color:#f19385;" data-darkreader-inline-color="">copter</span></strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>: public aircraft</strong></span></p><p style="line-height: normal;"><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>{</strong></span></p><p style="line-height: normal;"><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>&nbsp; &nbsp; void </strong></span><strong><span style="color: rgb(216, 79, 169); --darkreader-inline-color:#d270ac;" data-darkreader-inline-color="">fly</span></strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>(){}</strong> // 直升机盘旋!</span></p><p style="line-height: normal;"><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>};</strong></span></p></blockquote><p><br></p><p>以上代码可以看到,直升机类(copter)没有自己的加油方式,直接使用了基类提供的缺省加油的方式。此时我们来定义一个能驾驭多机型的王牌飞行员类:</p><p><br></p><p><em><span style="font-size: 14px; color: rgb(178, 178, 178); --darkreader-inline-color:#c3b49e;" data-darkreader-inline-color="">一个能王牌飞行员</span></em></p><blockquote><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">class pilot</span></strong></p><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">{</span></strong></p><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">&nbsp; &nbsp; void <span style="color: rgb(217, 33, 66); --darkreader-inline-color:#d86677;" data-darkreader-inline-color="">refuelPlane</span>(aircraft *p);</span></strong></p><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">&nbsp; &nbsp; void <span style="color: rgb(217, 33, 66); --darkreader-inline-color:#d86677;" data-darkreader-inline-color="">dirvePlane</span>(aircraft *p);</span></strong></p><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">};</span></strong></p></blockquote><p><br></p><p><em><span style="font-size: 14px; color: rgb(178, 178, 178); --darkreader-inline-color:#c3b49e;" data-darkreader-inline-color="">给我什么飞机我就加什么油</span></em></p><blockquote><p style="white-space: normal;line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">void pilot::refuelPlane(<span style="color: rgb(217, 33, 66); --darkreader-inline-color:#d86677;" data-darkreader-inline-color="">aircraft *p</span>)</span></strong></p><p style="white-space: normal;line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">{</span></strong></p><p style="white-space: normal;line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">&nbsp; &nbsp; p-&gt;refuel();</span></strong></p><p style="white-space: normal;line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">}</span></strong></p></blockquote><p style="white-space: normal;"><br></p><p style="white-space: normal;"><em><span style="font-size: 14px; color: rgb(178, 178, 178); --darkreader-inline-color:#c3b49e;" data-darkreader-inline-color="">给我什么飞机我就怎么飞</span></em></p><blockquote><p style="white-space: normal;line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">void pilot::dirvePlane(<span style="color: rgb(217, 33, 66); --darkreader-inline-color:#d86677;" data-darkreader-inline-color="">aircraft *p</span>)</span></strong></p><p style="white-space: normal;line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">{</span></strong></p><p style="white-space: normal;line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">&nbsp; &nbsp; p-&gt;fly();</span></strong></p><p style="white-space: normal;line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">}</span></strong></p></blockquote><p><br></p><p>很明显,我们接下来要给这位很浪的飞行员表演一下操纵各种飞行器的机会,我们来定义各种飞机然后丢给他去处理<br></p><p><br></p><p><em><span style="font-size: 14px; color: rgb(178, 178, 178); --darkreader-inline-color:#c3b49e;" data-darkreader-inline-color="">定义两架飞机,一架轰6K,一架武直10</span></em></p><blockquote><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">aircraft *<span style="color: rgb(217, 33, 66); --darkreader-inline-color:#d86677;" data-darkreader-inline-color="">H6K </span>= new bomber;</span></strong></p><p style="line-height: normal;"><strong><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color="">aircraft *<span style="color: rgb(217, 33, 66); --darkreader-inline-color:#d86677;" data-darkreader-inline-color="">WZ10&nbsp;</span>= new copter;</span></strong></p></blockquote><p><br></p><p><em><span style="font-size: 14px; color: rgb(178, 178, 178); --darkreader-inline-color:#c3b49e;" data-darkreader-inline-color="">来一个王牌飞行员,给H6K加油(加的是轰炸机特殊燃油),并且按照H6K的特点飞行</span></em></p><blockquote><p style="line-height: normal;"><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>pilot <span style="color: rgb(217, 33, 66); --darkreader-inline-color:#d86677;" data-darkreader-inline-color="">Jack</span>;</strong></span></p><p style="line-height: normal;"><span style="color: rgb(217, 33, 66); --darkreader-inline-color:#d86677;" data-darkreader-inline-color=""><strong>Jack</strong></span><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>.refuelPlane(H6K); &nbsp;// 加充轰炸机燃油</strong></span></p><p style="line-height: normal;"><span style="color: rgb(217, 33, 66); --darkreader-inline-color:#d86677;" data-darkreader-inline-color=""><strong>Jack</strong></span><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>.flyPlane(H6K); // 轰炸机实弹飞行</strong></span></p></blockquote><p><br></p><p><em><span style="font-size: 14px; color: rgb(178, 178, 178); --darkreader-inline-color:#c3b49e;" data-darkreader-inline-color="">给WZ10加油(加的是基类提供的通用燃油),按照WZ10的特点飞行</span></em></p><blockquote><p style="white-space: normal;"><span style="color: rgb(217, 33, 66); --darkreader-inline-color:#d86677;" data-darkreader-inline-color=""><strong>Jack</strong></span><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>.refuelPlane(WZ10); // 加充通用型燃油</strong></span></p><p style="white-space: normal;"><span style="color: rgb(217, 33, 66); --darkreader-inline-color:#d86677;" data-darkreader-inline-color=""><strong>Jack</strong></span><span style="color: rgb(0, 82, 255); --darkreader-inline-color:#4578e5;" data-darkreader-inline-color=""><strong>.flyPlane(WZ10); // 直升机盘旋</strong></span></p></blockquote><p style="white-space: normal;"><br></p><p style="white-space: normal;">上述代码体现了最经典的所谓多态的场景,给Jack不同的飞机,就能表现不同的结果。虚函数和纯虚函数都能做到这一点,区别是,子类如果不提供虚函数的实现,那就会自动调用基类的缺省方案。而子类如果不提供纯虚函数的实现,则编译将会失败。基类提供的纯虚函数实现版本,无法通过指向子类对象的基类类型指针或引用来调用,因此不能作为子类相应虚函数的备选方案。下面给出总结。</p><p style="white-space: normal;"><br></p><section class="" data-tools="135编辑器" data-id="91269" style="border-width: 0px; border-style: none; border-color: initial; box-sizing: border-box; --darkreader-inline-border-top: initial; --darkreader-inline-border-right: initial; --darkreader-inline-border-bottom: initial; --darkreader-inline-border-left: initial;" data-darkreader-inline-border-top="" data-darkreader-inline-border-right="" data-darkreader-inline-border-bottom="" data-darkreader-inline-border-left=""><section style="text-align:center;"><img class="" data-ratio="0.0598669623059867" data-src="http://mmbiz.qpic.cn/mmbiz_png/d0YYOX6Zlby3pIrMZzOlNLBFgYEWJI3PDaKcmftE3HfjOkwXxpjTG32TUXD90sTrwrqtBhSmsLpK7VicOFgonrg/0?wx_fmt=png" data-type="png" data-w="451" style="display: inline; width: 300px !important; height: auto !important; visibility: visible !important;" title="欧式古典 分割线" _width="300px" src="http://mmbiz.qpic.cn/mmbiz_png/d0YYOX6Zlby3pIrMZzOlNLBFgYEWJI3PDaKcmftE3HfjOkwXxpjTG32TUXD90sTrwrqtBhSmsLpK7VicOFgonrg/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" crossorigin="anonymous" data-fail="0"></section></section><p><br></p><p>第一,<strong>当基类的某个成员方法,在大多数情形下都应该由子类提供个性化实现,但基类也可以提供一个备选方案的时候,请将其设计为虚函数</strong>。例如飞行器的加油动作,每种不同的飞行器原则上都应该有自己的个性化的加充然后的方式,但也不免可以有一种通用的然后和加充方式。</p><p><br></p><p>第二,<strong>当基类的某个成员方法,必须由子类提供个性化实现的时候,请将其设计为纯虚函数</strong>。例如飞行器的飞行动作,逻辑上每种飞行器都必须提供为其特殊设计的个性化飞行行为,而不应该有任何一种“通用的飞行方式”。</p><p><br></p><p>第三,<strong>使用一个基类类型的指针或者引用,来指向子类对象,进而调用经由子类复写了的个性化的虚函数,这是C++实现多态性的一个最经典的场景</strong>。</p><p><br></p><p>第四,基类提供的纯虚函数的实现版本,并非为了多态性考虑,因为指向子类对象的基类指针和引用无法调用该版本。<strong>纯虚函数在基类中的实现跟多态性无关,它只是提供了一种语法上的便利,在变化多端的应用场景中留有后路</strong>。</p><p><br></p><p>第五,<strong>虚函数和普通的函数实际上是存储在不同的区域的</strong>,虚函数所在的区域是可被覆盖(也称复写override)的,每当子类定义相同名称的虚函数时就将原来基类的版本给覆盖了,另一侧面也说明了为什么基类中声明的虚函数在后代类中不需要另加声明一律自动为虚函数,因为它所存储的位置不会发生改变。而普通函数的存储区域不会覆盖,每个类都有自己独立的区域互不相干。</p><p><br></p><p>最后附一幅草图以供参考</p><p><img data-s="300,640" data-type="jpeg" data-src="https://mmbiz.qpic.cn/mmbiz_jpg/d0YYOX6Zlby3pIrMZzOlNLBFgYEWJI3PN6GG3sY9otrSozjIaZfxneKRHRUOCpKQGgBcXx3NCl5OPwia8bpxwBA/0?wx_fmt=jpeg" data-copyright="0" style="width: 677px !important; height: auto !important; visibility: visible !important;" class="" data-ratio="0.5625" data-w="1280" _width="677px" src="https://mmbiz.qpic.cn/mmbiz_jpg/d0YYOX6Zlby3pIrMZzOlNLBFgYEWJI3PN6GG3sY9otrSozjIaZfxneKRHRUOCpKQGgBcXx3NCl5OPwia8bpxwBA/640?wx_fmt=jpeg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" crossorigin="anonymous" data-fail="0"></p><p><br></p><section class="" data-source="bj.96weixin.com" style="white-space: normal;"><section class="" data-ele="imb" style="border-width: 0px;border-style: none;"><section style="margin-top: 10px;box-sizing: border-box;font-family: 微软雅黑;"><section class="" style="padding: 10px; background-color: rgb(182, 228, 253); text-align: justify; --darkreader-inline-bgcolor:#16445b;" data-darkreader-inline-bgcolor=""><p style="overflow-wrap: break-word;line-height: 1.5em;"><span style="color: inherit; font-size: 14px; --darkreader-inline-color: inherit;" data-darkreader-inline-color="">识别下面二维码进入&nbsp;</span><span style="font-size: 16px; color: rgb(171, 25, 66); font-weight: bold; --darkreader-inline-color:#df7d93;" data-darkreader-inline-color="">微店</span><span style="color: inherit; font-size: 14px; --darkreader-inline-color: inherit;" data-darkreader-inline-color=""><span style="font-size: 16px;"><strong><span style="color: rgb(171, 25, 66); --darkreader-inline-color:#df7d93;" data-darkreader-inline-color="">●</span></strong><strong><span style="color: rgb(171, 25, 66); --darkreader-inline-color:#df7d93;" data-darkreader-inline-color="">秘籍酷&nbsp;</span></strong></span>瞅一眼呗!也许有你喜欢的东西</span></p></section><section class="" data-wxsrc="http://mmbiz.qpic.cn/mmbiz_png/p6Vlqvia1Uicx4P4GotoIy3EibRibkEgicfCyW3ntgWjeGSa0qhpNRn7pLzBdTBYzJ6XOPPINUTaIczxAP6zFfMM9FQ/0?wx_fmt=png" style="height: 20px;background-image: url(&quot;http://mmbiz.qpic.cn/mmbiz_png/d0YYOX6ZlbxAMtYaYL4el9dAzOJGcj02HD6Aw7JbAdVclKtZOyrsU1ricnWH4H7wc8J0FnyNajFZmwIkEyd9DOg/0?wx_fmt=png&quot;);background-repeat: no-repeat;background-size: 50% 100%;"><br></section></section></section></section><section class="" data-source="bj.96weixin.com" style="white-space: normal;line-height: 25.6px;"><section class="" data-width="320px" style="margin-right: auto;margin-left: auto;border-style: none;width: 320px;clear: both;overflow: hidden;"><section data-width="100%" style="padding-right: 0.1em;width: 320px;float: left;"><p><img class=" __bg_gif" data-ratio="0.6583333333333333" data-src="http://mmbiz.qpic.cn/mmbiz/d0YYOX6ZlbzEJj7MCYjbiaJpFRSnbYNq9hhibppd5ib2OYnibsbFGiaskrdGqxGwmGdQhPtC09E0yvQaGtmic7xf4kTw/0?wx_fmt=gif" data-type="gif" data-w="600" data-width="319px" height="190" width="295" style="width: 295px !important; height: auto !important; visibility: visible !important;" _width="295px" src="http://mmbiz.qpic.cn/mmbiz/d0YYOX6ZlbzEJj7MCYjbiaJpFRSnbYNq9hhibppd5ib2OYnibsbFGiaskrdGqxGwmGdQhPtC09E0yvQaGtmic7xf4kTw/0?wx_fmt=gif&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" data-order="1" data-fail="0"><br></p><section style="margin-top: -10.5em; margin-left: 0.2em; padding: 0.2em 1em; float: left; font-size: 18px; text-align: center; color: rgb(255, 255, 255); opacity: 0.95; --darkreader-inline-color:#fbf7f1;" data-darkreader-inline-color=""><img class="" data-src="https://mmbiz.qpic.cn/mmbiz_jpg/d0YYOX6ZlbwxEuFWMbayZLMTA3E4icqQ0CLoyEht9RTIJgDMyicz8AAxbhtsomhiclSMficf1XlEY1ykKsVWAQXt3w/0?wx_fmt=jpeg" data-width="130px" title="" vspace="0" border="0" data-type="jpeg" data-cropselx1="0" data-cropselx2="130" data-cropsely1="0" data-cropsely2="130" data-copyright="0" data-ratio="1" data-w="210" style="width: 130px !important; height: auto !important; visibility: visible !important;" _width="130px" src="https://mmbiz.qpic.cn/mmbiz_jpg/d0YYOX6ZlbwxEuFWMbayZLMTA3E4icqQ0CLoyEht9RTIJgDMyicz8AAxbhtsomhiclSMficf1XlEY1ykKsVWAQXt3w/640?wx_fmt=jpeg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" crossorigin="anonymous" data-fail="0"></section></section></section></section></div>

虚函数和纯虚函数详解相关推荐

  1. C++虚函数、纯虚函数、虚析构、纯虚析构、动态绑定和抽象类详解。

    目录 1.虚函数的概念 2.虚函数的定义 3.虚函数的作用 4.用虚函数实现多态的方法 5.动态绑定和静态绑定 6.纯虚函数和抽象类 7.虚析构和纯虚析构 1.虚函数的概念 在C++程序中我们经常可以 ...

  2. 38.【C++ 虚函数 纯虚函数 虚基类 (最全详解)】

    虚函数.虚基类.纯虚函数 (一).虚函数 1.什么是虚函数: 2.虚函数的格式: 3.关于虚函数的注意事项: 4.虚函数的作用: 5.虚函数访问格式 6.虚函数的各种疑难杂症 [当指针是基类.但虚函数 ...

  3. 虚函数、纯虚函数、虚继承、多继承

    来源:http://www.tnove.com/?p=57 C++的一个特征是多太,其中多态主要表现在 1.编译时多态  函数overload实现 2.运行是多态  虚函数override实现 其中虚 ...

  4. C++经典问题_06 虚函数和纯虚函数以及多态

    文章目录 一. 虚函数和纯虚函数以及多态的概念 二. 虚函数详解 ① 虚函数的定义 ② 虚函数和普通函数重写时候的区别 ③ 虚函数的常见错误 ④ 如何避免虚函数的使用错误 三. 虚函数指针和虚函数表 ...

  5. 但并不从包含函数声明的接口派生_C++的虚函数和纯虚函数

    虚函数:类成员函数前面添加virtual关键字,则该函数被称为虚函数. 纯虚函数:在虚函数的基础上,在函数末尾加上 = 0. class Animal {public: virtual void Sh ...

  6. 一口气搞懂《虚函数和纯虚函数》

    学习C++的多态性,你必然听过虚函数的概念,你必然知道有关她的种种语法,但你未必了解她为什么要那样做,未必了解她种种行为背后的所思所想.深知你不想在流于表面语法上的蜻蜓点水似是而非,今天我们就一起来揭 ...

  7. C++知识点51——虚函数与纯虚函数(下)

    接上一篇文章https://blog.csdn.net/Master_Cui/article/details/109957146 10.练习 示例 class base { public:base() ...

  8. C++ 在继承中虚函数、纯虚函数、普通函数,三者的区别

    C++ 在继承中虚函数.纯虚函数.普通函数,三者的区别 1.虚函数(impure virtual) C++的虚函数主要作用是"运行时多态",父类中提供虚函数的实现,为子类提供默认的 ...

  9. 虚函数与纯虚函数的区别

    虚函数:为了方便使用多态特性,常常需要在基类中定义虚函数. 纯虚函数: 1.原因与虚函数相同: 2.在很多情况下,基类本身生成的对象是不合理的: 虚函数与纯虚函数的区别: 1.类里声明为虚函数的话,这 ...

最新文章

  1. Expandable Table的Demo
  2. 高校计算机通识教育目标,美国高校计算机通识教育研究
  3. lucas定理 FOJ 2020 组合
  4. PHP安装包中VC9和VC11的含义
  5. 【WebRTC---入门篇】(十五)WebRTC信令服务器实现
  6. OSPF工作机制——OSPF邻居状态机详解(附图)
  7. linux网络流量实时监控工具之iptraf 【个人比较喜欢用的流量监控软件】
  8. 【java】System.arraycopy为什么快
  9. 前端常用插件、工具类库汇总,新手必收藏!!!
  10. Sybase 事务和嵌套事务
  11. linux 打包 压缩
  12. Microsoft AJAX Library的beta2版发布
  13. WinPcap vs Npcap
  14. C语言实现图的关键路径算法
  15. AARRR模型:用户激活指标+方法,很实用!
  16. Nginx反向代理服务器解决负责均衡问题
  17. Promise对象的resolve回调函数和reject回调函数使用
  18. 一个非计算机专业的 软考中级 网络工程师考试之路
  19. his使用-重置密码
  20. python so反编译_使用cython把python编译so

热门文章

  1. hdu 1251 统计难题(求前缀出现了多少次)
  2. jzoj 6302. 提高组
  3. 3. 跟踪标记 (Trace Flag) 1204, 1222 抓取死锁信息
  4. 【Java基础】用LinkedList实现一个简单栈的功能
  5. 2014-07-28 使用Axure RP进行手机端BBS的原型设计
  6. Jquery对复选框的操作
  7. calayer 与uiview
  8. 外中断02 - 零基础入门学习汇编语言70
  9. java 先序遍历_二叉树的前序中序后序遍历(java代码)
  10. 微信社交小程序服务器,Day12-微信小程序实战-交友小程序-搭建服务器与上传文件到后端...