Virtual Table — RTTI — typeinfo dynamic_cast 模板编程 orocos OperationCaller 类的设计
virtual table
關于虛表,查看這個牛人寫的系列blog, 其中詳細介紹了MI(multiple inheritence)和SI情況下虛表是如何工作的,以及其信息是以何種格式保存的,寫的簡明扼要,鞭辟入里:
對于每一個類(不是對象),如果其有虛函數(shù),則對應有一個虛表。每個對象包含一個或者多個在vptr(在MI情況下),該vptr指向與這個類對應的虛表. 虛表和成員函數(shù)一樣,不構成類的大小,而vptr則參與計算類的大小(sizeof).
RTTI
即 Run-time Type Identification, 是c++提供一種能夠在運行時確定對象的類型的方法。c++提供兩種RTTI的操作:
1 . typeid 返回一個 std::type_info 的結構,包含可以唯一確定該對象的類型的信息。
typeid 都忽略 cv 限定符(即 typeid(T) == typeid(const T) )
一般來說,對于一個具有多態(tài)的類(就是有virtual member function的類),其typeinfo是保存在vtable中的,這樣dynamic_cast的就可以直接獲取其類的信息。但是對于非polymorphic type的類型來說,typeinfo一般是由編譯器保存在全局某個數(shù)據(jù)段中,用戶只可以通過typeid來獲取,不能直接得到其地址。
check: https://stackoverflow.com/questions/7155652/where-is-type-info-object-stored
2 . dynamic_cast 判斷該基類指針到底指向哪一類派生類:
dynamic_cast 就是運用 RTTI 來判斷該指針所指的對象的 typeinfo (一般位于 virtual table 的第一項 see book: Inside The C++ Object Model) 是否能在指定類的繼承樹中找到匹配的,如果找不到則返回空指針(see link: http://www.stroustrup.com/fast_dynamic_casting.pdf)。更多關于 RTTI 和 typeinfo see link: https://en.wikipedia.org/wiki/Run-time_type_information
模板編程 — orocos OperationCaller:
幾個關鍵點:使用一系列 function_traits 和 type_traits 來獲得相關函數(shù)的信息,并保存在接口的成員變量中,使用boost::function保存該調(diào)用實體,定義 operator() 統(tǒng)一調(diào)用形式,使用 dynamic_cast 來判斷兩個函數(shù)(類)簽名是否一致等等。
C++11 type_traits 實現(xiàn): https://functionalcpp.wordpress.com/2013/08/05/function-traits/
template<class SignatureT>class OperationCaller: public internal::InvokerSignature<boost::function_traits<SignatureT>::arity, // 參數(shù)個數(shù)SignatureT, // 函數(shù)形式boost::shared_ptr< base::OperationCallerBase<SignatureT> > >, // 生成函數(shù)指針public base::OperationCallerBaseInvoker...其中 InvokerSignature 是一些列重載函數(shù),并且在其中定義 operator() 函數(shù)用于調(diào)用具體函數(shù),形式如下:
template<class F, class ToInvoke>struct InvokerSignature<1,F,ToInvoke> // <int, 函數(shù)形式, 函數(shù)指針> , 根據(jù)int的值不同(參數(shù)個數(shù))定義一系列重載函數(shù){typedef typename boost::function_traits<F>::result_type result_type;typedef typename boost::function_traits<F>::arg1_type arg1_type;InvokerSignature() : impl() {}InvokerSignature(ToInvoke implementation) : impl(implementation) {}~InvokerSignature() {}/*** Invoke this operator if the method has one argument.*/result_type operator()(arg1_type a1) // 調(diào)用形式{if (impl)return impl->call( a1 );return NA<result_type>::na(); // 如果函數(shù)指針為空,返回默認值}result_type call(arg1_type a1) {return operator()(a1);}SendHandle<F> send(arg1_type a1){if (impl)return impl->send(a1);return SendHandle<F>();}protected:ToInvoke impl;};泛型編程幾個要素: 模板、 typedef、重載、traits
Boost.FunctionTypes 參考
http://www.boost.org/doc/libs/1_59_0/libs/function_types/doc/html/boost_functiontypes/introduction.html
Boost.TypeTraits (function_traits)參考
http://www.boost.org/doc/libs/1_59_0/libs/type_traits/doc/html/index.html
Boost.CallTraits( 參數(shù)類型轉換 )
http://www.boost.org/doc/libs/master/libs/utility/call_traits.htm
根據(jù)模板選擇重載函數(shù) enable_if:
http://eli.thegreenplace.net/2014/sfinae-and-enable_if/
And a good book:
http://ultra.sdk.free.fr/misc/docs/Addison.Wesley.C++.Template.Metaprogramming.Concepts.Tools.and.Techniques.from.Boost.and.Beyond.pdf
總結
以上是生活随笔為你收集整理的Virtual Table — RTTI — typeinfo dynamic_cast 模板编程 orocos OperationCaller 类的设计的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 鱼和水
- 下一篇: numpy的快速傅里叶变换