日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于多态

發布時間:2024/2/28 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于多态 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

多態又分為靜態多態和動態多態。

靜態多態其實就是函數重載,動態多態就是一般我們所說的多態。

多態作為面向對象的三大特征之一,需要另外兩大特征:封裝、繼承的支持。

本文主要講講,我看了一點《深度探索C++模型》總結多態是怎樣實現的。

1.C++內存布局

C++對象主要可以有如下幾種成員:

(1)數據成員

①static數據成員

②nonstatic數據成員

(2)函數成員

①static函數成員

②nonstatic函數成員

③virtual函數成員


其中,nonstatic數據成員和virtual函數成員是要占用,變量的內存空間的。

其他成員都是使用一個公共的靜態區域。

具體地講,每一個類對象會為其每一個nonstatic數據成員持有一個指針,而對于其所有的虛函數,會持有1個指針vptr,這個指針指向一個表vtbl,這個表里每一個位置也是一個指針,指向該類的各個虛函數。


2.多態的實現

在定義父類和子類的時候,父類對象的與子類對象都擁有vptr這個成員,但是父類的vptr指向的vtbl里面的指針指向的虛函數是父類的版本。

子類的vptr指向的btbl里面的指針指向的虛函數是子類的版本。

這個vptr指向的btbl里面放的虛函數是哪一個版本是由構造器、拷貝復制運算符決定的。

如果是構造一個父類對象,就是指向父類的虛函數,如果構造一個子類對象就是指向一個子類的虛函數。

如果把一個子類對象,強制轉換為一個父類對象,其vptr也會變為指向父類虛函數的。


但是當我們把一個父類的指針賦值一個指向了子類的指針,這個時候首先會發生切割,將子類多出來的成員給切割掉。

因為不同類型的指針,會限定從該地址開始的后面的范圍的內存布局。

但是由于指針賦值,并沒有調用子類或者父類的構造器,并且vptr是子類對象與父類對象所共有的,所以并沒有被切割。

所以這個時候如果一個指針開始指向了一個子類對象,現在通過這個指針調用的虛函數版本就是子類的,雖然這個指針現在是一個父類指針。


注意:

2016/06/01更新

我用G++ 4.9.2編譯器驗證出來的一些信息

1.vtbl源自父類的會不會也用來填裝子類新加入的虛函數
會。
如果父類沒有虛函數,子類有就會在子類額外區間多一個vptr
如果父類有虛函數,父類區間的vptr指向的vtbl也會存放子類新建的虛函數。


2.vtbl會不會同時用來記錄虛基類信息
不會。有一個vptr,有一個vbtr
但是如果虛基類里面沒有數據成員的話,是不會產生一個vbtr用于訪問數據成員的。


3.如果是多重繼承的虛擬基類是采用多少個vbtr
多重繼承了多少個虛擬基類就會有多少個vbtr


4.如果是多階繼承
對于一階,如果有單獨定義的變量,那么每一階就會產生一個vbtr


總結:
GCC的這些貌似少了很多優化,但是它好像是講vptr和vbtr都用一個指針來實現的,然后進行了相應地處理。

總結

以上是生活随笔為你收集整理的关于多态的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。