C++?重載運(yùn)算符在HotSpot?VM中的應(yīng)用小結(jié)
C++支持運(yùn)算符重載,對于Java開發(fā)者來說,這個(gè)可能比較陌生一些,因?yàn)镴ava不支持運(yùn)算符重載。運(yùn)算符重載本質(zhì)上來說就是函數(shù)重載。下面介紹一下HotSpot VM中的運(yùn)算符重載。
1、內(nèi)存分配與釋放
在C++中可以通過new運(yùn)算符創(chuàng)建一個(gè)C++的類實(shí)例,這個(gè)操作實(shí)際上上包含了如下3個(gè)步驟:
- 調(diào)用operator new的標(biāo)準(zhǔn)庫函數(shù)。此函數(shù)會分配一塊內(nèi)存空間以便函存儲相應(yīng)類型的實(shí)例。
- 調(diào)用相應(yīng)類的構(gòu)造函數(shù)
- 返回一個(gè)指向該對象的指針
同樣,可以delete運(yùn)算符釋放對應(yīng)的內(nèi)存,實(shí)際執(zhí)行如下2個(gè)步驟:
- 調(diào)用相應(yīng)類的析構(gòu)函數(shù)
- 調(diào)用operator delete標(biāo)準(zhǔn)庫函數(shù)釋放內(nèi)存。
由于C++沒有Java的GC托管技術(shù),所以分配出來的內(nèi)存時(shí)刻要惦記著釋放,這是一件非常不容易的事情。通常的做法是,內(nèi)存申請和釋放集中到一個(gè)地方管理,所以才會有Metaspace或Arena這些相對復(fù)雜一些的內(nèi)存管理機(jī)制。
有了我們自己設(shè)計(jì)的內(nèi)存管理機(jī)制后,就可以重載new運(yùn)算符,讓實(shí)例從特定的內(nèi)存空間中申請和釋放內(nèi)存了,例如HotSpot VM在Klass類中重載了new運(yùn)算符:
void* Klass::operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) throw() { // 在元數(shù)據(jù)區(qū)分配內(nèi)存空間 void* x = Metaspace::allocate( loader_data, word_size, false, /*read_only*/ MetaspaceObj::ClassType, CHECK_NULL ); return x; }
在使用new關(guān)鍵字創(chuàng)建Klass或子類的實(shí)例時(shí),都會調(diào)用Metaspace::allocate()函數(shù)從元數(shù)據(jù)區(qū)分配內(nèi)存;在Klass類中,我們沒有看到重載delete運(yùn)算符,因?yàn)閯h除一個(gè)類并沒有那么簡單,需要借助GC來完成。元數(shù)據(jù)區(qū)具體管理內(nèi)存的辦法,以及分配和釋放的邏輯可參看《深入剖析Java虛擬機(jī):源碼剖析與實(shí)例詳解》中的8.2節(jié)。
在HotSpot VM中重載new和delete運(yùn)算符的地方非常多,不過oop并不是這樣做的,這應(yīng)該是考慮到它相對復(fù)雜的內(nèi)存分配邏輯和初始化過程吧。
2、句柄
關(guān)于句柄,可以參考 http://www.dbjr.com.cn/article/141842.htm 。句柄要間接操作實(shí)例,讓GC能夠集中掃描到棧中引用到的Java對象。
句柄的相關(guān)定義如下:
class Handle { private: oop *_handle; // oop的類型為oopDesc* protected: oop obj() const { return _handle == NULL ? (oop) NULL : *_handle; } oop non_null_obj() const { return *_handle; } public: // 重載了()、->和==運(yùn)算符 oop operator()() const { return obj(); } oop operator->() const { return non_null_obj(); } bool operator==(oop o) const { return obj() == o; } bool operator==(const Handle &h) const { return obj() == h.obj(); } };
句柄中重載了()、->和==運(yùn)算符,我們可以這樣操作:
oop obj1 = ...; // 將對象封裝為句柄 Handle h1(obj1); // 獲取被封裝的對象,會調(diào)用到operator()()函數(shù),這個(gè)函數(shù)返回*_handle oop obj2 = h1(); // 直接調(diào)用oop中定義的相關(guān)函數(shù),會調(diào)用到operator->()函數(shù), // 在這個(gè)函數(shù)中獲取_handle值后調(diào)用_handle->print()函數(shù) h1->print();
這大大簡化了相關(guān)操作的簡潔性,操作句柄就感覺和操作oop是一樣的效果
到此這篇關(guān)于C++ 重載運(yùn)算符在HotSpot VM中的應(yīng)用的文章就介紹到這了,更多相關(guān)C++ 重載運(yùn)算符內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言驅(qū)動(dòng)開發(fā)之內(nèi)核通過PEB獲取進(jìn)程參數(shù)
PEB結(jié)構(gòu)(Process Envirorment Block Structure)其中文名是進(jìn)程環(huán)境塊信息。本文將通過PEB實(shí)現(xiàn)獲取進(jìn)程參數(shù),感興趣的小伙伴可以了解一下2022-10-10Qt QTreeWidget 樹形結(jié)構(gòu)實(shí)現(xiàn)代碼
Qt中實(shí)現(xiàn)樹形結(jié)構(gòu)可以使用QTreeWidget類,也可以使用QTreeView類,QTreeWidget繼承自QTreeView類,接下來通過本文給大家介紹Qt QTreeWidget 樹形結(jié)構(gòu)實(shí)現(xiàn)代碼,需要的朋友可以參考下2021-11-11C++中如何將operator==定義為類的成員函數(shù)
這篇文章主要介紹了C++中如何將operator==定義為類的成員函數(shù),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01基于C中一個(gè)行壓縮圖的簡單實(shí)現(xiàn)代碼
首先簡單說一下什么是行壓縮圖,其實(shí)嚴(yán)格意義上應(yīng)該是行壓縮矩陣2013-05-05C++ 遞歸遍歷文件并計(jì)算MD5的實(shí)例代碼
在本篇文章里小編給大家整理的是一篇關(guān)于C++ 遞歸遍歷文件并計(jì)算MD5的實(shí)例代碼,有興趣的朋友們可以學(xué)習(xí)參考下。2021-07-07