虛函數和純虛函數的區別

***************************************************

更多精彩,歡迎進入:http://shop115376623.taobao.com

***************************************************


首先:強調一個概念

定義一個函數為虛函數,不代表函數為不被實現的函數。
定義他為虛函數是為了允許用基類的指針來調用子類的這個函數。
定義一個函數為純虛函數,才代表函數沒有被實現。

定義純虛函數是為了實現一個接口,起到一個規范的作用,規范繼承這個類的程序員必須實現這個函數。
1、簡介
假設我們有下面的類層次:
[cpp]?view plaincopy
  1. class?A??
  2. {??
  3. public:??
  4. ????virtual?void?foo()??
  5. ????{??
  6. ????????cout<<"A::foo()?is?called"<<endl;??
  7. ????}??
  8. };??
  9. class?B:public?A??
  10. {??
  11. public:??
  12. ????void?foo()??
  13. ????{??
  14. ????????cout<<"B::foo()?is?called"<<endl;??
  15. ????}??
  16. };??
  17. int?main(void)??
  18. {??
  19. ????A?*a?=?new?B();??
  20. ????a->foo();???//?在這里,a雖然是指向A的指針,但是被調用的函數(foo)卻是B的!??
  21. ????return?0;??
  22. }??
???? 這個例子是虛函數的一個典型應用,通過這個例子,也許你就對虛函數有了一些概念。它虛就虛在所謂“推遲聯編”或者“動態聯編”上,一個類函數的調用并不是在編譯時刻被確定的,而是在運行時刻被確定的。由于編寫代碼的時候并不能確定被調用的是基類的函數還是哪個派生類的函數,所以被成為“虛”函數。
????虛函數只能借助于指針或者引用來達到多態的效果。

C++純虛函數
一、定義
 純虛函數是在基類中聲明的虛函數,它在基類中沒有定義,但要求任何派生類都要定義自己的實現方法。在基類中實現純虛函數的方法是在函數原型后加“=0”
 virtual void funtion1()=0
二、引入原因
  1、為了方便使用多態特性,我們常常需要在基類中定義虛擬函數。
  2、在很多情況下,基類本身生成對象是不合情理的。例如,動物作為一個基類可以派生出老虎、孔雀等子類,但動物本身生成對象明顯不合常理。
  為了解決上述問題,引入了純虛函數的概念,將函數定義為純虛函數(方法:virtual ReturnType Function()= 0;),則編譯器要求在派生類中必須予以重寫以實現多態性。同時含有純虛擬函數的類稱為抽象類,它不能生成對象。這樣就很好地解決了上述兩個問題。

聲明了純虛函數的類是一個抽象類。所以,用戶不能創建類的實例,只能創建它的派生類的實例。
純虛函數最顯著的特征是:它們必須在繼承類中重新聲明函數(不要后面的=0,否則該派生類也不能實例化),而且它們在抽象類中往往沒有定義。
定義純虛函數的目的在于,使派生類僅僅只是繼承函數的接口。
純虛函數的意義,讓所有的類對象(主要是派生類對象)都可以執行純虛函數的動作,但類無法為純虛函數提供一個合理的缺省實現。所以類純虛函數的聲明就是在告訴子類的設計者,“你必須提供一個純虛函數的實現,但我不知道你會怎樣實現它”。


抽象類的介紹
抽象類是一種特殊的類,它是為了抽象和設計的目的為建立的,它處于繼承層次結構的較上層。
(1)抽象類的定義:? 稱帶有純虛函數的類為抽象類。
(2)抽象類的作用:
抽象類的主要作用是將有關的操作作為結果接口組織在一個繼承層次結構中,由它來為派生類提供一個公共的根,派生類將具體實現在其基類中作為接口的操作。所以派生類實際上刻畫了一組子類的操作接口的通用語義,這些語義也傳給子類,子類可以具體實現這些語義,也可以再將這些語義傳給自己的子類。
(3)使用抽象類時注意:

??? 抽象類只能作為基類來使用,其純虛函數的實現由派生類給出。如果派生類中沒有重新定義純虛函數,而只是繼承基類的純虛函數,則這個派生類仍然還是一個抽象類。如果派生類中給出了基類純虛函數的實現,則該派生類就不再是抽象類了,它是一個可以建立對象的具體的類。
??? 抽象類是不能定義對象的。


總結:

1、純虛函數聲明如下:?virtual void funtion1()=0; 純虛函數一定沒有定義,純虛函數用來規范派生類的行為,即接口。包含純虛函數的類是抽象類,抽象類不能定義實例,但可以聲明指向實現該抽象類的具體類的指針或引用。
2、虛函數聲明如下:virtual ReturnType FunctionName(Parameter);虛函數必須實現,如果不實現,編譯器將報錯,錯誤提示為:
error LNK****: unresolved external symbol "public: virtual void __thiscall ClassName::virtualFunctionName(void)"
3、對于虛函數來說,父類和子類都有各自的版本。由多態方式調用的時候動態綁定。
4、實現了純虛函數的子類,該純虛函數在子類中就編程了虛函數,子類的子類即孫子類可以覆蓋該虛函數,由多態方式調用的時候動態綁定。
5、虛函數是C++中用于實現多態(polymorphism)的機制。核心理念就是通過基類訪問派生類定義的函數。
6、在有動態分配堆上內存的時候,析構函數必須是虛函數,但沒有必要是純虛的。
7、友元不是成員函數,只有成員函數才可以是虛擬的,因此友元不能是虛擬函數。但可以通過讓友元函數調用虛擬成員函數來解決友元的虛擬問題。
8、析構函數應當是虛函數,將調用相應對象類型的析構函數,因此,如果指針指向的是子類對象,將調用子類的析構函數,然后自動調用基類的析構函數。

有純虛函數的類是抽象類,不能生成對象,只能派生。他派生的類的純虛函數沒有被改寫,那么,它的派生類還是個抽象類。
定義純虛函數就是為了讓基類不可實例化化
因為實例化這樣的抽象數據結構本身并沒有意義。
或者給出實現也沒有意義
實際上我個人認為純虛函數的引入,是出于兩個目的
1、為了安全,因為避免任何需要明確但是因為不小心而導致的未知的結果,提醒子類去做應做的實現。
2、為了效率,不是程序執行的效率,而是為了編碼的效率。

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

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

相關文章

工作日志WebRoot--編輯頁關于處理兩個關聯的選擇框

案例&#xff1a;點擊編輯&#xff0c;彈出界面后每個欄目都有一個默認的數值&#xff0c;但若其中一個選擇框發生更改&#xff0c;則觸發另一選擇框內的數據發生變動&#xff08;例如組織機構選擇發生變動&#xff0c;則相對應的組織機構的下屬機構也發生變動&#xff09;。 解…

linux下r語言畫圖,linux命令行下使用R語言繪圖實例講解

使用系統&#xff1a;centos 6.4 64bit在R語言中可以使用png()等函數生成圖片&#xff0c;例如&#xff1a; png("aa.png")可以生成圖片。但是如果你是通過shell遠程連接到系統上&#xff0c;可能會碰到如下錯誤&#xff1a;> png("aa.png")錯誤于.Exte…

Windows Mobile Gprs連接與數據傳輸

此模塊分兩部分完成&#xff0c;傳輸數據用socket &#xff0c;要使用socket在ppc上進行數據傳輸&#xff0c;就要誰讓ppc自動連接gprs 。其中套接字和gprs鏈接分別進行說明。 一 &#xff0c;應用程序在進行其它所需的Windows Sockets API調用需要進行一次成功的WSAStartup()調…

C語言變量的類型和存儲位置

*************************************************** 更多精彩&#xff0c;歡迎進入&#xff1a;http://shop115376623.taobao.com *************************************************** 1. C語言變量主要分為全局變量、靜態全局變量、局部變量、靜態局部變量和寄存器變量。…

nginx+tomcat負載均衡

最近練習nginxtomcat負載均衡。根據一些資料整理了大體思路&#xff0c;最終實現了1個nginx2個tomcat負載均衡。 安裝JDK 1》進入安裝目錄&#xff0c;給所有用戶添加可執行的權限 #chmod x jdk-7u67-linux-i586.rpm //不知這步有沒有必要 2》安裝JDK 輸入命令#rpm –ivh jdk-7…

linux 最強shell,最牛B 的 Linux Shell 命令(一)

引言Shell作為Unix系操作系統當中最有魅力且不可或缺的組件&#xff0c;經過數十載的洗禮不僅沒有被淘汰&#xff0c;而且愈加變得成熟穩健&#xff0c;究其原因&#xff0c;大概因為它是個非常穩固的粘合劑&#xff0c;能夠把大量功能強大的組件任意配搭&#xff0c;總能很好很…

更改Docker默認的images存儲位置

Docker的鏡像以及一些數據都是在/var/lib/docker目錄下&#xff0c;它占用的是Linux的系統分區&#xff0c;也就是下面的/dev/vda1,當有多個鏡像時&#xff0c;/dev/vda1的空間可能不足&#xff0c;我們可以把docker的數據掛載到數據盤&#xff0c;例如&#xff1a;/dev/vdb目錄…

malloc/free和new/delete的區別

*************************************************** 更多精彩&#xff0c;歡迎進入&#xff1a;http://shop115376623.taobao.com *************************************************** malloc與free是C/C語言的標準庫函數&#xff0c;new/delete是C的運算符。它們都可用于…

HDU 1217 Arbitrage (Floyd + SPFA判環)

題目鏈接&#xff1a;HDU 1217 Arbitrage 簡單的貨幣轉換問題&#xff0c;給定多種貨幣&#xff0c;以及貨幣之間的匯率&#xff0c;問能否通過貨幣的轉換實現收益。 例如&#xff1a; 1 US Dollar buys 0.5 British pound, 1 British pound buys 10.0 French francs, and 1 F…

linux libbz2.so.1,libbz2.so.1.0 = not found 試過了鏈接和設置環境變量

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓LD_LIBRARY_PATH. ldd steamui.solinux-gate.so.1 > (0xf7700000)libtier0_s.so > ./libtier0_s.so (0xf648e000)libv8.so > ./libv8.so (0xf5ba3000)libvideo.so > ./libvideo.so (0xf57e2000)libvstdlib_s.so > .…

對互聯網中常見地圖的坐標系探討

文章版權由作者李曉暉和博客園共有&#xff0c;若轉載請于明顯處標明出處&#xff1a;http://www.cnblogs.com/naaoveGIS/。 1.背景 目前項目中使用百度地圖、高德地圖、谷歌中國地圖、天地圖的需求越來越多&#xff0c;這里我跟大家一起對各地圖使用的坐標系做一個簡單的探討。…

unsigned int + int型結果分析

*************************************************** 更多精彩&#xff0c;歡迎進入&#xff1a;http://shop115376623.taobao.com *************************************************** 代碼如下&#xff1a; “//”后為調試中的結果 unsigned int a 6; //a 6 …

MAC OSX在視圖port哪個程序占用,殺死進程的方法

sudo lsof -i :9000COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAMEjava 61342 a 313u IPv6 0x1111111111111 0t0 TCP *:cslistener (LISTEN)在此基礎PID殺死進程&#xff1a;sudo kill -9 61342 版權聲明&#xff1a;本文博主原創文章&am…

訊飛輸入法有沒有Linux,Debian testing 安裝訊飛輸入法 - Linux系統與應用 - LinuxApp - 水木社區...

突然發現Deepin發行版帶有訊飛輸入法&#xff0c;于是折騰了一會&#xff0c;安裝好了這個輸入法&#xff0c;現把安裝過程分享如下&#xff1a;軟件包的依賴&#xff1a;Package: iflyimeVersion: 0.9.962Section: develPriority: optionalArchitecture: amd64Depends: libboo…

幾種C#程序讀取MAC地址的方法

原文:幾種C#程序讀取MAC地址的方法以下是收集的幾種C#程序讀取MAC地址的方法&#xff0c;示例中是讀取所有網卡的MAC地址&#xff0c;如果僅需要讀取其中一個&#xff0c;稍作修改即可。 1 通過IPConfig命令讀取MAC地址 ///<summary>///根據截取ipconfig /all命令的輸出流…

寫出float x 與“零值”比較的if語句——一道面試題分析

*************************************************** 更多精彩&#xff0c;歡迎進入&#xff1a;http://shop115376623.taobao.com *************************************************** 寫出float x 與“零值”比較的if語句 請寫出 float x 與“零值”比較的 if 語句&…

Conditional project or library reference in Visual Studio

Conditional project or library reference in Visual Studio In case you were wondering why you haven’t heard from me in a while, I’ve been busy, which isn’t really of much importance unless you know me on a personal level. What is relevant is that I recen…

linux 雙mipi攝像頭,VS-RK3399 在linux系統下面調試Mipi camera接口介紹

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓debian系統目前支持Usb camera是沒有問題&#xff0c;走UVC功能接口。那么mipi 接口camera和并口接口的camera&#xff0c;在Debian系統怎么設置呢&#xff0c;其實原理一樣&#xff0c;也走uvc接口封裝函數.下面深圳視壯給大家簡單…

HTTP必知必會

2019獨角獸企業重金招聘Python工程師標準>>> HTTP消息HTTP請求消息HTTP響應消息消息首行請求行響應行消息頭部請求頭請求頭消息正文請求正文響應正文Web服務器把接收到的HTTP請求消息封裝成request對象&#xff0c;作為service的參數傳入service函數&#xff0c;ser…

float數據在計算機內存中的存儲方法

*************************************************** 更多精彩&#xff0c;歡迎進入&#xff1a;http://shop115376623.taobao.com *************************************************** 浮點型變量在計算機內存中占用4字節&#xff08;Byte&#xff09;,即32-bit。遵循IEEE…