亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++中的動(dòng)態(tài)分派在HotSpot?VM中的應(yīng)用小結(jié)

 更新時(shí)間:2023年09月25日 08:52:53   作者:鳩摩(馬智)  
多態(tài)是面向?qū)ο缶幊陶Z(yǔ)言的重要特性,它允許基類(lèi)的指針或引用指向派生類(lèi)的對(duì)象,而在具體訪問(wèn)時(shí)實(shí)現(xiàn)方法的動(dòng)態(tài)綁定,這篇文章主要介紹了C++的動(dòng)態(tài)分派在HotSpot?VM中的重要應(yīng)用,需要的朋友可以參考下

眾所周知,多態(tài)是面向?qū)ο缶幊陶Z(yǔ)言的重要特性,它允許基類(lèi)的指針或引用指向派生類(lèi)的對(duì)象,而在具體訪問(wèn)時(shí)實(shí)現(xiàn)方法的動(dòng)態(tài)綁定。C++ 和 Java 作為當(dāng)前最為流行的兩種面向?qū)ο缶幊陶Z(yǔ)言,其內(nèi)部對(duì)于多態(tài)的支持對(duì)于單繼承的實(shí)現(xiàn)非常類(lèi)似。

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

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

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

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

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

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

內(nèi)存布局如下:

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)的指針,其類(lèi)型為void**, 這說(shuō)明它是一個(gè)void*指針。類(lèi)似于在類(lèi)Base1中定義了如下類(lèi)似的偽代碼:

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

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

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

從如上的例子我們應(yīng)該能夠得到如下一些結(jié)論:

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

對(duì)于第2點(diǎn)來(lái)說(shuō),HotSpot VM的設(shè)計(jì)者充分考慮了這個(gè)情況,所以在一些類(lèi)的設(shè)計(jì)上能不用虛函數(shù)就絕對(duì)不用,例如oop繼承體系下的所有類(lèi)都不會(huì)用虛函數(shù),因?yàn)橛幸粋€(gè)Java實(shí)例就會(huì)有一個(gè)oop,現(xiàn)在的應(yīng)用程序一般都有過(guò)千萬(wàn)的實(shí)例,那我們可以算一下,每個(gè)實(shí)例要多出8個(gè)字節(jié)存儲(chǔ)指向虛表的指針,那要消耗掉多少內(nèi)存呢?!

下面我們來(lái)談?wù)劦?點(diǎn)提到的動(dòng)態(tài)分派。先來(lái)看一下單繼承情況下C++的動(dòng)態(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(){}; 
};

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


只有加virtual關(guān)鍵字的虛函數(shù)才會(huì)存在于虛函數(shù)表中,也就是這些虛函數(shù)需要?jiǎng)討B(tài)分派。當(dāng)子類(lèi)重寫(xiě)了父類(lèi)的方法時(shí),動(dòng)態(tài)分派能準(zhǔn)確根據(jù)接收者類(lèi)型找到實(shí)際需要調(diào)用的函數(shù)。

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

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

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

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

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

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

相關(guān)文章

  • C++淺析內(nèi)存分區(qū)模型概念與示例

    C++淺析內(nèi)存分區(qū)模型概念與示例

    在了解內(nèi)存分區(qū)之前,我們先來(lái)聊一聊為什么要進(jìn)行內(nèi)存分區(qū)。在進(jìn)行了內(nèi)存分區(qū)之后,在不同的區(qū)域存放的數(shù)據(jù),會(huì)有不同的生命周期,從而會(huì)讓程序員的編程變得更加靈活
    2022-09-09
  • 利用Matlab制作一款刮刮樂(lè)抽獎(jiǎng)特效

    利用Matlab制作一款刮刮樂(lè)抽獎(jiǎng)特效

    七夕節(jié)還不知道送啥,教你用MATLAB制作一款刮刮樂(lè)抽獎(jiǎng)特效,讓她的手氣決定她的禮物。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-03-03
  • C++實(shí)現(xiàn)LeetCode(198.打家劫舍)

    C++實(shí)現(xiàn)LeetCode(198.打家劫舍)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(198.打家劫舍),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • QT中QByteArray與char、int、float之間的互相轉(zhuǎn)化

    QT中QByteArray與char、int、float之間的互相轉(zhuǎn)化

    本文主要介紹了QT中QByteArray與char、int、float之間的互相轉(zhuǎn)化,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • C++ STL中一些常用算法總結(jié)

    C++ STL中一些常用算法總結(jié)

    都說(shuō)STL是數(shù)據(jù)容器與算法的高度組合,在前面的文章中我們介紹了常見(jiàn)的幾種容器,vector、list、map、deque等,今天我們?cè)賮?lái)介紹下STL中常用的一些算法,需要的朋友可以參考下
    2024-02-02
  • c++基礎(chǔ)使用STL的注意點(diǎn)詳解

    c++基礎(chǔ)使用STL的注意點(diǎn)詳解

    這篇文章主要為大家介紹了c++基礎(chǔ)使用STL的注意點(diǎn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-12-12
  • C語(yǔ)言安全編碼數(shù)組記法的一致性

    C語(yǔ)言安全編碼數(shù)組記法的一致性

    這篇文章主要介紹了C語(yǔ)言安全編碼數(shù)組記法的一致性,需要的朋友可以參考下
    2014-07-07
  • C語(yǔ)言字符串旋轉(zhuǎn)問(wèn)題的深入講解

    C語(yǔ)言字符串旋轉(zhuǎn)問(wèn)題的深入講解

    這篇文章主要給大家介紹了關(guān)于C語(yǔ)言字符串旋轉(zhuǎn)問(wèn)題的相關(guān)資料,文中給出了詳細(xì)的實(shí)現(xiàn)方法,并對(duì)每種方法進(jìn)行了分析和示例代碼,需要的朋友可以參考下
    2021-09-09
  • 詳解C語(yǔ)言用malloc函數(shù)申請(qǐng)二維動(dòng)態(tài)數(shù)組的實(shí)例

    詳解C語(yǔ)言用malloc函數(shù)申請(qǐng)二維動(dòng)態(tài)數(shù)組的實(shí)例

    這篇文章主要介紹了詳解C語(yǔ)言用malloc函數(shù)申請(qǐng)二維動(dòng)態(tài)數(shù)組的實(shí)例的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下
    2017-10-10
  • Qt之簡(jiǎn)單的異步操作實(shí)現(xiàn)方法

    Qt之簡(jiǎn)單的異步操作實(shí)現(xiàn)方法

    這篇文章主要介紹了Qt之簡(jiǎn)單的異步操作實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11

最新評(píng)論