自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C++多態(tài)性基本概念講述

開發(fā) 后端
C++多態(tài)性主要是通過(guò)虛函數(shù)來(lái)實(shí)現(xiàn)的。我們只有在重寫了虛函數(shù)之后才能被看做是C++多態(tài)性。在這里將會(huì)對(duì)此做一個(gè)詳細(xì)介紹。

C++編程語(yǔ)言是一款應(yīng)用廣泛,支持多種程序設(shè)計(jì)的計(jì)算機(jī)編程語(yǔ)言。我們今天就會(huì)為大家詳細(xì)介紹其中C++多態(tài)性的一些基本知識(shí),以方便大家在學(xué)習(xí)過(guò)程中對(duì)此能夠有一個(gè)充分的掌握。#t#

前幾天筆試的時(shí)候碰到考C++多態(tài)性的題目,因?yàn)椴皇亲约旱膶I(yè)不是純做軟件開發(fā),C++學(xué)習(xí)不是很好,做得有點(diǎn)混亂?;貋?lái)以后立刻查了相關(guān)資料,大概明白了一點(diǎn),可能以后解題的時(shí)候不會(huì)亂了。

先摘下一些網(wǎng)上的書上的基本概念。

多態(tài)性可以簡(jiǎn)單地概括為“一個(gè)接口,多種方法”,程序在運(yùn)行時(shí)才決定調(diào)用的函數(shù),它是面向?qū)ο缶幊填I(lǐng)域的核心概念。多態(tài)(polymorphisn),字面意思多種形狀。

C++多態(tài)性是通過(guò)虛函數(shù)來(lái)實(shí)現(xiàn)的,虛函數(shù)允許子類重新定義成員函數(shù),而子類重新定義父類的做法稱為覆蓋(override),或者稱為重寫。(這里我覺得要補(bǔ)充,重寫的話可以有兩種,直接重寫成員函數(shù)和重寫虛函數(shù),只有重寫了虛函數(shù)的才能算作是體現(xiàn)了C++多態(tài)性)而重載則是允許有多個(gè)同名的函數(shù),而這些函數(shù)的參數(shù)列表不同,允許參數(shù)個(gè)數(shù)不同,參數(shù)類型不同,或者兩者都不同。編譯器會(huì)根據(jù)這些函數(shù)的不同列表,將同名的函數(shù)的名稱做修飾,從而生成一些不同名稱的預(yù)處理函數(shù),來(lái)實(shí)現(xiàn)同名函數(shù)調(diào)用時(shí)的重載問(wèn)題。但這并沒有體現(xiàn)多態(tài)性。

多態(tài)與非多態(tài)的實(shí)質(zhì)區(qū)別就是函數(shù)地址是早綁定還是晚綁定。如果函數(shù)的調(diào)用,在編譯器編譯期間就可以確定函數(shù)的調(diào)用地址,并生產(chǎn)代碼,是靜態(tài)的,就是說(shuō)地址是早綁定的。而如果函數(shù)調(diào)用的地址不能在編譯器期間確定,需要在運(yùn)行時(shí)才確定,這就屬于晚綁定。

那么多態(tài)的作用是什么呢,封裝可以使得代碼模塊化,繼承可以擴(kuò)展已存在的代碼,他們的目的都是為了代碼重用。而多態(tài)的目的則是為了接口重用。也就是說(shuō),不論傳遞過(guò)來(lái)的究竟是那個(gè)類的對(duì)象,函數(shù)都能夠通過(guò)同一個(gè)接口調(diào)用到適應(yīng)各自對(duì)象的實(shí)現(xiàn)方法。

最常見的用法就是聲明基類的指針,利用該指針指向任意一個(gè)子類對(duì)象,調(diào)用相應(yīng)的虛函數(shù),可以根據(jù)指向的子類的不同而實(shí)現(xiàn)不同的方法。如果沒有使用虛函數(shù)的話,即沒有利用C++多態(tài)性,則利用基類指針調(diào)用相應(yīng)的函數(shù)的時(shí)候,將總被限制在基類函數(shù)本身,而無(wú)法調(diào)用到子類中被重寫過(guò)的函數(shù)。因?yàn)闆]有多態(tài)性,函數(shù)調(diào)用的地址將是一定的,而固定的地址將始終調(diào)用到同一個(gè)函數(shù),這就無(wú)法實(shí)現(xiàn)一個(gè)接口,多種方法的目的了。

筆試的題目

  1. #include <stdio.h> 
  2. class A  
  3. {  
  4. public:  
  5. void foo()  
  6. {  
  7. printf("1");  
  8. }  
  9. virtual void fuu()  
  10. {  
  11. printf("2");  
  12. }  
  13. };  
  14. class B:public A  
  15. {  
  16. public:  
  17. void foo()  
  18. {  
  19. printf("3");  
  20. }  
  21. void fuu()  
  22. {  
  23. printf("4");  
  24. }  
  25. };  
  26. int main()  
  27. {  
  28. A a;  
  29. B b;  
  30. A *p = &a;  
  31. p->foo();  
  32. p->fuu();  
  33. p = &b;  
  34. p->foo();  
  35. p->fuu();  
  36. return 0;  

第一個(gè)p->foo()和p->fuu()都很好理解,本身是基類指針,指向的又是基類對(duì)象,調(diào)用的都是基類本身的函數(shù),因此輸出結(jié)果就是1、2。

第二個(gè)p->foo()和p->fuu()則是基類指針指向子類對(duì)象,正式體現(xiàn)多態(tài)的用法,p->foo()由于指針是個(gè)基類指針,指向是一個(gè)固定偏移量的函數(shù),因此此時(shí)指向的就只能是基類的foo()函數(shù)的代碼了,因此輸出的結(jié)果還是1。而p->fuu()指針是基類指針,指向的fuu是一個(gè)虛函數(shù),由于每個(gè)虛函數(shù)都有一個(gè)虛函數(shù)列表,此時(shí)p調(diào)用fuu()并不是直接調(diào)用函數(shù),而是通過(guò)虛函數(shù)列表找到相應(yīng)的函數(shù)的地址,因此根據(jù)指向的對(duì)象不同,函數(shù)地址也將不同,這里將找到對(duì)應(yīng)的子類的fuu()函數(shù)的地址,因此輸出的結(jié)果也會(huì)是子類的結(jié)果4.

筆試的題目中還有一個(gè)另類測(cè)試方法。即

 

  1. B *ptr = (B *)&a;  
  2. ptr->foo();  
  3. ptr->fuu(); 

 

問(wèn)這兩調(diào)用的輸出結(jié)果。這是一個(gè)用子類的指針去指向一個(gè)強(qiáng)制轉(zhuǎn)換為子類地址的基類對(duì)象。結(jié)果,這兩句調(diào)用的輸出結(jié)果是3,2。

并不是很理解這種用法,從原理上來(lái)解釋,由于B是子類指針,雖然被賦予了基類對(duì)象地址,但是ptr->foo()在調(diào)用的時(shí)候,由于地址偏移量固定,偏移量是子類對(duì)象的偏移量,于是即使在指向了一個(gè)基類對(duì)象的情況下,還是調(diào)用到了子類的函數(shù),雖然可能從始到終都沒有子類對(duì)象的實(shí)例化出現(xiàn)。

而ptr->fuu()的調(diào)用,可能還是因?yàn)镃++多態(tài)性的原因,由于指向的是一個(gè)基類對(duì)象,通過(guò)虛函數(shù)列表的引用,找到了基類中foo()函數(shù)的地址,因此調(diào)用了基類的函數(shù)。由此可見多態(tài)性的強(qiáng)大,可以適應(yīng)各種變化,不論指針是基類的還是子類的,都能找到正確的實(shí)現(xiàn)方法。

責(zé)任編輯:曹凱 來(lái)源: 博客園
相關(guān)推薦

2010-02-05 17:34:37

C++函數(shù)模板

2010-01-28 16:16:32

C++多態(tài)性

2009-09-01 15:08:18

C#多態(tài)性

2009-08-28 16:48:50

C#多態(tài)性

2010-02-02 10:33:22

C++引用

2010-02-03 13:22:07

C++時(shí)間

2010-02-05 12:57:20

C++ kdevelo

2010-02-03 14:36:47

C++仿函數(shù)

2010-02-01 17:24:41

C++循環(huán)語(yǔ)句

2010-02-02 15:30:05

C++ include

2010-02-03 11:11:18

C++類型轉(zhuǎn)換

2010-02-02 13:41:01

C++類繼承

2009-09-01 14:51:19

C#多態(tài)性

2010-02-06 14:04:58

C++內(nèi)存使用機(jī)制

2010-02-04 13:56:24

C++類模板特化

2010-02-04 10:08:00

C++靜態(tài)成員函數(shù)

2010-01-15 13:30:50

VB.NET Prog

2010-02-06 09:53:26

C++ void

2010-02-06 15:58:10

C++集合初始化

2010-02-04 17:39:48

C++字符串類型
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)