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