最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++中的動態(tài)分派在HotSpot?VM中的應用小結

 更新時間:2023年09月25日 08:52:53   作者:鳩摩(馬智)  
多態(tài)是面向對象編程語言的重要特性,它允許基類的指針或引用指向派生類的對象,而在具體訪問時實現(xiàn)方法的動態(tài)綁定,這篇文章主要介紹了C++的動態(tài)分派在HotSpot?VM中的重要應用,需要的朋友可以參考下

眾所周知,多態(tài)是面向對象編程語言的重要特性,它允許基類的指針或引用指向派生類的對象,而在具體訪問時實現(xiàn)方法的動態(tài)綁定。C++ 和 Java 作為當前最為流行的兩種面向對象編程語言,其內部對于多態(tài)的支持對于單繼承的實現(xiàn)非常類似。

首先來體現(xiàn)一下C++的動態(tài)分派,如下:

class Base1{
public: 
 int base1_var1; 
 int base1_var2; 
 void func(){}  
};

C++中有函數(shù)的動態(tài)分派,就類似于Java中方法的多態(tài)。而C++實現(xiàn)動態(tài)分派主要就是通過虛函數(shù)來完成的,非虛函數(shù)在編譯時就已經(jīng)確定調用目標。C++中的虛函數(shù)通過關鍵字virtual來聲明,如上函數(shù)func()沒有virtual關鍵字,所以是非虛函數(shù)。
查看內存布局,如下:

1>  class Base1  size(8):
1>   +---
1>   0   | base1_var1
1>   4   | base1_var2
1>   +---

非虛函數(shù)不會影響內存布局?!?/p>

class Base1{
public: 
 int base1_var1; 
 int base1_var2; 
 virtual void base1_fun1() {}
};

內存布局如下:

1>  class Base1  size(16):
1>   +---
1>   0   | {vfptr}
1>   8   | base1_var1
1>  12   | base1_var2
1>   +---

在64位環(huán)境下,指針占用8字節(jié),而vfptr就是指向虛函數(shù)表(vtable)的指針,其類型為void**, 這說明它是一個void*指針。類似于在類Base1中定義了如下類似的偽代碼:

void* vtable[1] = {  &Base1::base1_fun1  };
const void**  vfptr = &vtable[0];

這個非常類似于Java虛擬機中對Java方法動態(tài)分派時的虛函數(shù)表(可參看深入剖析Java虛擬機:源碼剖析與實例詳解》一書第6.3節(jié))。

虛函數(shù)表是屬于類的,而不是屬于某個具體的對象,一個類只需要一個虛函數(shù)表即可。同一個類的所有對象都使用同一個虛函數(shù)表。為了指定對象的虛函數(shù)表,對象內部包含一個虛函數(shù)表的指針,來指向自己所使用的虛函數(shù)表。?為了讓每個包含虛函數(shù)表的類的對象都擁有一個虛函數(shù)表指針,編譯器在類中添加了一個指針,用來指向虛函數(shù)表。這樣,當類的對象在創(chuàng)建時便擁有了這個指針,且這個指針的值會自動被設置為指向類的虛函數(shù)表。

從如上的例子我們應該能夠得到如下一些結論:

  • C++的動態(tài)分派需要明確用virtual關鍵字指明,而Java中的方法默認就是動態(tài)分派,這也體現(xiàn)出兩種語言設計理念的不同,C++不想讓用戶為用不到的功能付出代價,Java更看重開發(fā)效率,將一些復雜的底層控制全權托管給虛擬機;
  • C++中只要有虛函數(shù),就會在類中有一個虛函數(shù)表,而且類的每個實例都會多出一個指向虛函數(shù)表的指針。

對于第2點來說,HotSpot VM的設計者充分考慮了這個情況,所以在一些類的設計上能不用虛函數(shù)就絕對不用,例如oop繼承體系下的所有類都不會用虛函數(shù),因為有一個Java實例就會有一個oop,現(xiàn)在的應用程序一般都有過千萬的實例,那我們可以算一下,每個實例要多出8個字節(jié)存儲指向虛表的指針,那要消耗掉多少內存呢?!

下面我們來談談第1點提到的動態(tài)分派。先來看一下單繼承情況下C++的動態(tài)分派。

class Person{ 
     . . . 
 public : 
    void init(){} // 非virtual方法
    virtual void sing (){}; 
    virtual void dance (){}; 
 }; 
class Girl : public Person{ 
     . . . 
public : 
   virtual void sing(){}; 
   virtual void speak(){}; 
};

動態(tài)分派的過程大概如下圖所示。


只有加virtual關鍵字的虛函數(shù)才會存在于虛函數(shù)表中,也就是這些虛函數(shù)需要動態(tài)分派。當子類重寫了父類的方法時,動態(tài)分派能準確根據(jù)接收者類型找到實際需要調用的函數(shù)。

在HotSpot VM中有非常多使用動態(tài)分派的例子,如Klass繼承體系下的類有個oop_oop_iterate_v_m()函數(shù),在發(fā)生YGC時,由于老年代也會有引用指向年輕代對象,所以必須通過卡表找到這些可能的對象,在找到這些對象后,這些對象的哪些區(qū)域是引用還要進一步借助Klass來完成,如一般的對象會調用InstanceKlass中的oop_oop_iterate_v_m()函數(shù),而java.lang.Class對象會調用InstanceMirrorKlass類中的oop_oop_iterate_v_m()函數(shù)。

下面看一下Java的動態(tài)分派。舉個例子如下:

class Person{ 
  	void sing (){}
	void dance (){}
}
class Girl extends Person{
	void sing(){}
	void speak(){}
}

了解過Java虛函數(shù)表的人可能知道,類中許多的方法都會放到虛函數(shù)表中,這就是我們前面說的,Java中的方法默認都是動態(tài)分派的。
動態(tài)分派的過程大概如下圖所示。

從Object繼承下來5個方法,final、靜態(tài)方法和構造方法不會進入虛函數(shù)表中。final關鍵字與C++的virtual有著相反的作用。
JVM的方法調用指令有四個,分別是 invokestatic,invokespecial,invokesvirtual 和 invokeinterface。前兩個是靜態(tài)綁定,后兩個是動態(tài)綁定的,invokevirtual表示調用虛方法,也就是會查虛函數(shù)表進行調用,而invokeinterface表示調用接口方法,會有個接口函數(shù)表,這里暫不介紹。

到此這篇關于C++中的動態(tài)分派在HotSpot VM中的應用小結的文章就介紹到這了,更多相關C++動態(tài)分派HotSpot VM應用內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C語言strlen函數(shù)全方位講解

    C語言strlen函數(shù)全方位講解

    在C語言中我們要獲取字符串的長度,可以使用strlen函數(shù),strlen函數(shù)計算字符串的長度時,直到空結束字符,但不包括空結束字符,因為 strlen函數(shù)時不包含最后的結束字符的,因此一般使用strlen函數(shù)計算的字符串的長度會比使用sizeof計算的字符串的字節(jié)數(shù)要小
    2022-09-09
  • C++中decltype關鍵字的實現(xiàn)

    C++中decltype關鍵字的實現(xiàn)

    decltype是C++11引入的關鍵字,用于在編譯時精確推導表達式或變量的類型而不執(zhí)行表達式,本文就來詳細的介紹一下C++ decltype關鍵字的使用,感興趣的可以了解一下
    2026-02-02
  • C語言結構體數(shù)組同時賦值的另類用法

    C語言結構體數(shù)組同時賦值的另類用法

    今天小編就為大家分享一篇關于C語言結構體數(shù)組同時賦值的另類用法,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • C語言 ffmpeg與sdl實現(xiàn)播放視頻同時同步時鐘詳解

    C語言 ffmpeg與sdl實現(xiàn)播放視頻同時同步時鐘詳解

    使用ffmpeg和sdl實現(xiàn)播放視頻后,需要再實現(xiàn)時鐘同步才能正常的播放視頻,尤其是有音頻的情況,我們通常需要將視頻同步到音頻來確保音畫同步
    2022-09-09
  • C語言詳細實現(xiàn)猜拳游戲流程

    C語言詳細實現(xiàn)猜拳游戲流程

    在學習了循環(huán)、分支、和函數(shù)之后,可以寫一些簡單的小游戲來給自己的編程之路增添一份樂趣。不僅提升了編碼能力,還可以邊學邊玩,簡直妙哉妙哉
    2022-05-05
  • c++將字符串轉數(shù)字的實例方法

    c++將字符串轉數(shù)字的實例方法

    在本篇文章里小編給大家整理的是關于c++將字符串轉數(shù)字的實例方法,有需要的朋友們可以參考下。
    2020-02-02
  • C語言?推理證明帶環(huán)鏈表詳細過程

    C語言?推理證明帶環(huán)鏈表詳細過程

    單鏈表中同樣也有具有挑戰(zhàn)性的題目,鏈表的帶環(huán)問題可以說是眾多難題中的佼佼者,在這里可能更看重的是邏輯推理和證明的過程
    2022-04-04
  • C++中獲取隨機數(shù)的常用方法小結

    C++中獲取隨機數(shù)的常用方法小結

    這篇文章主要為大家詳細介紹了C++中獲取隨機數(shù)的幾種常用方法,文中的示例代碼講解詳細,具有一定的借鑒價值,感興趣的小伙伴可以了解下
    2025-01-01
  • 詳解C語言之預處理(上)

    詳解C語言之預處理(上)

    這篇文章主要介紹了C語言程序的預處理,小編覺得這篇文章寫的還不錯,需要的朋友可以參考下,希望能夠給你帶來幫助
    2021-11-11
  • C++拋出和接收異常的順序

    C++拋出和接收異常的順序

    這篇文章主要介紹了C++拋出和接收異常的順序,幫助大家更好的理解和學習C++,感興趣的朋友可以了解下
    2020-08-08

最新評論

定南县| 平泉县| 广德县| 林口县| 彭山县| 双城市| 桐梓县| 和顺县| 永川市| 汪清县| 新源县| 新野县| 晴隆县| 松桃| 张家口市| 大城县| 临沂市| 广南县| 鄂托克前旗| 怀柔区| 四平市| 嘉定区| 新泰市| 广宁县| 乐山市| 贵阳市| 台湾省| 格尔木市| 陈巴尔虎旗| 正蓝旗| 四会市| 且末县| 宁都县| 图片| 威宁| 益阳市| 马关县| 安仁县| 社会| 和静县| 武鸣县|