Google protocol buffer 的反射機制和應用
阿新 • • 發佈:2019-02-07
何謂反射?
我在工作中大量使用了 google protocal buffer, 為了方便描述, 下文簡稱為 pb. pb 的作用和基本使用方法在這裡就不再陳述, 相關的文章網上很多. 這裡主要介紹 pb 的反射機制. 什麼是反射機制呢? 該機制能在執行時, 對於任意一個類, 都能知道這個類的所有屬性和方法; 對於任意一個物件, 都能呼叫它的任意一個方法和屬性; 簡言之, 反射機制使程式設計師可以動態獲取物件資訊以及動態呼叫物件的方法. 下面用兩個例子來解釋什麼是反射. 1. 動態獲取物件資訊 對於一個 c++ 類 Player , 如果標準提供一個函式 Show(Player), 可以取到 Player 的所有成員函式和變數的名字. 我們就說 Show 函式可以動態獲取物件的資訊. 2. 動態呼叫物件的方法. Player 類裡有一個函式 AddMoney(int a), playerA 是一個Player 物件. 如果標準提供一個函式 Call(playerA, "AddMoney", 100), 能達到 playerA.AddMoney(100) 相同的效果. 我們就說 Call 函式可以動態呼叫物件的方法. 當然, c++ 沒有 Show 和 Call 這兩個函式, 所以c++不具備反射機制. 提供了 Show 和 Call, 或是能達到同樣功能的函式的系統, 就實現了反射機制.pb 的反射
知道了什麼是反射, 我們來看看 pb 是如何實現的. 首先認識幾個關鍵類.
google::protobuf::Message
這是使用者自定義訊息的基類. 系統會為給每個使用者自定義訊息例項化一個預設物件, 物件用 Message* 儲存. Message 類定義了 New() 虛擬函式, 可以返回本物件的一份新的例項, 型別和本物件的真實型別相同. 拿到了 Message*,
不用知道它的具體型別, 就可以建立和它一樣型別的物件. 通過 New() 函式建立的物件, 需要使用者自己釋放. New() 函式是執行緒安全的.
google::protobuf::MessageFactory
管理所有自動例項化的 Message 物件. 它自身也會被自動例項化, 通過靜態函式 generated_factory() 能拿到該物件指標. 通過成員函式 每一個使用者自定義訊息, 都對應一個 Descriptor 物件. 該物件描述了訊息的格式. 系統會為每個訊息的 Descriptor 例項化一個預設物件. google::protobuf::DescriptorPool 管理所有自動例項化的 Descriptot 物件. 它自身也會自動被例項化, 通過靜態函式 generated_pool() 能拿到該物件指標. 通過成員函式