虛函數和純虛函數詳解

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>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/382618.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/382618.shtml
英文地址,請注明出處:http://en.pswp.cn/news/382618.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++ 繼承中的同名成員的情況01

class Base { public:Base(){this->m_A 100;}void func(){cout << "Base中的Func調用" << endl;}void func(int a){cout << "Base中的Func(int a)調用" << endl;}int m_A; }; class Son : public Base { public:Son(){this-&g…

進程前臺運行后臺運行的相關命令

command& 讓進程在后臺運行jobs 查看后臺運行的進程fg %n 讓后臺運行的進程n到前臺來bg %n 讓進程n到后臺去&#xff1b; ctrl z 可以將一個正在前臺執行的命令放到后臺&#xff0c;并且暫停

西安電子科技大學求職打點

這兩天 一直在西安電子科技大學找工作&#xff0c;感覺自己漸漸失去了學習的狀態&#xff0c;本來很 多會的知識點都已經不會了。   今天休息一天&#xff0c;沒有去招聘會&#xff0c;看了看相關的知識&#xff0c;做了做題。也希望自己盡快恢復學習的感覺&#xff0c;溫故…

C++ 泛型編程模板 之 函數模板初步01

#define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std;void mySwapInt(int &a, int &b) {int temp a;a b;b temp; } void mySwapDouble(double &a, double &b) {double temp a;a b;b temp; } //利用模板實現通用交換函數 temp…

grep參數說明及常用用法

grep參數說明及常用用法 查看文件內容 [koulocalhost ~]$ more size.txt b124230 b034325 a081016 m7187998 m7282064 a022021 a061048 m9324822 b103303 a013386 b044525 m8987131 B081016 M45678 B103303 BADc2345 [] : 查看符合范圍內的信息 [koulocalho…

C++ 普通函數與函數模板 區別以及調用規則01

//普通函數 和 函數模板 區別 int myPlus(int a, int b) {return a b; }template<class T> T myPlus2(T a, T b) {return a b; }void test01() {int a 10;int b 20;char c c;cout << myPlus(a, c) << endl; //隱式類型轉換 將 char c轉為 int類型//myP…

C++ 模板的局限性以及解決01

#define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; #include <string>class Person { public:Person(string name, int age){this->m_Name name;this->m_Age age;}string m_Name;int m_Age; };//通過模板進行兩個數據比較 templat…

進程的狀態與種類

● 運行&#xff1a;正占用處理器   ● 就緒&#xff1a;只要獲得處理器即可運行。   ● 阻塞&#xff1a;正等待某個事件&#xff08;如I/O完成&#xff09;的發生。  在不少系統中&#xff0c;還增加了兩種基本狀態&#xff1a;   ● 新狀態&#xff1a;一個進程剛剛…

C++ 類模板語法初步01

#define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; #include <string> //類模板 //template下面緊跟著的內容是類&#xff0c;那么這個類稱為 類模板 // 類模板中的類型 也可以有默認參數 // 泛型編程 類型參數化template<class NAM…

int * p =NULL;和*p =NULL的區別a和a的區別

1.int * p NULL;和*p NULL的區別 1 .int * p NULL int *pNULL&#xff1b;定義一個指針變量p&#xff0c;其指向的內存里面保存的是int類型的數據&#xff1b;再定義變量p的同時把p的值設置為0x00000000&#xff0c; 而不是把*p的值設置為0x00000000 2.*p NULL int i 10&am…

當我們說TCP是可靠協議時,我們真正表達的是什么

轉載出處&#xff1a;https://blog.csdn.net/dog250/article/details/82177299 很明確地說&#xff0c;從通信意義上推敲&#xff0c;TCP一點都不可靠。一個抽象的協議&#xff0c;怎么可能左右介質來保證可靠&#xff0c;不存在的。但凡是經由某種介質的通信行為均不可能是絕對…

IP地址=192.168.127.101,子網掩碼255.255.255.192,計算網絡地址,主機號,廣播地址和主機最大數

純手寫&#xff0c;如果哪寫錯了&#xff0c;還希望指正 IP地址192.168.127.101&#xff0c;子網掩碼255.255.255.192&#xff0c;計算網絡地址&#xff0c;主機號&#xff0c;廣播地址和主機最大數 255.255.255.192子網掩碼轉換成二進制為 11111111.11111111.11111111.11000…

C++ 類模板遇到繼承的問題以及解決

#define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std;template<class T> class Base {T m_A; //子類創建時候 必須要知道T的類型&#xff0c;才能給父類中的m_A分配內存 };template<class T1 , class T2> class Son :public Base<T2…

A B C類IP地址的判斷

IP地址131.153.12.71是一個&#xff08;&#xff09;類IP地址。 IP地址分類A類網絡的IP地址范圍為1.0.0.1&#xff0d;127.255.255.254&#xff1b; B類網絡的IP地址范圍為&#xff1a;128.1.0.1&#xff0d;191.255.255.254&#xff1b; C類網絡的IP地址范圍為&#xff1a;1…

linux sshd啟動失敗 sshd re-exec requires execution with an absolute path

sshd 提示 sshd re-exec requires execution with an absolute path提示 需要絕對路徑來執行 sshd&#xff0c; 剛開始學 不知道怎么用絕對路徑來啟動&#xff1f; 以后明白了&#xff0c; 這里再補充上 google 使用 service sshd restart 輸入密碼來啟動

有一個小白程序員,寫了一個只能對5個數字進行排序的函數,現在有25個不重復的數字,

題目&#xff1a;有一個小白程序員&#xff0c;寫了一個只能對5個數字進行排序的函數&#xff0c;現在有25個不重復的數字&#xff0c;請問小白同學最少調用幾次該函數&#xff0c;可以找出其中最大的三個數&#xff1f; A.5 B.6 C.7 D.8 答案&#xff1a;C 解析&#xf…

ubuntu修改ls顯示目錄的顏色

ls查看目錄&#xff0c; 背景是黑色的&#xff0c;目錄顏色是深藍色&#xff0c;基本看不清楚。 解決辦法 因為ubuntu下的/etc/目錄里沒有DIR_COLORS, 所以費了點勁兒。 2. 利用dircolors命令&#xff0c;查看我們的系統當前的文件名稱顯示顏色的值&#xff0c;然后利用管道重…

初始序列為1 8 6 2 5 4 7 3一組數采用堆排序,當建堆(小根堆)完畢時,堆所對應的二叉樹中序遍歷序列為

初始序列為1 8 6 2 5 4 7 3一組數采用堆排序&#xff0c;當建堆&#xff08;小根堆&#xff09;完畢時&#xff0c;堆所對應的二叉樹中序遍歷序列為&#xff1a;&#xff08;&#xff09; 8 3 2 5 1 6 4 7 3 2 8 5 1 4 6 7 3 8 2 5 1 6 7 4 8 2 3 5 1 4 7 6 A

設一組初始記錄關鍵字序列為(25,50,15,35,80,85,20,40,36,70)進行一趟歸并后的結果為

設一組初始記錄關鍵字序列為(25&#xff0c;50&#xff0c;15&#xff0c;35&#xff0c;80&#xff0c;85&#xff0c;20&#xff0c;40&#xff0c;36&#xff0c;70)&#xff0c;其中含有5個長度為2的有序子表&#xff0c;則用歸并排序的方法對該記錄關鍵字序列進行一趟歸并…

C++ 異常基本語法

#define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std;class MyException { public:void printError(){cout << "我自己的異常類的錯誤" << endl;} };class Person { public:Person(){cout << "Person的構造函數&q…