日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Virtual Table — RTTI — typeinfo dynamic_cast 模板编程 orocos OperationCaller 类的设计

發(fā)布時間:2023/12/20 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Virtual Table — RTTI — typeinfo dynamic_cast 模板编程 orocos OperationCaller 类的设计 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

virtual table
關于虛表,查看這個牛人寫的系列blog, 其中詳細介紹了MI(multiple inheritence)和SI情況下虛表是如何工作的,以及其信息是以何種格式保存的,寫的簡明扼要,鞭辟入里:

  • http://hacksoflife.blogspot.com/2007/02/c-objects-part-2-single-inheritance.html
  • http://hacksoflife.blogspot.com/2007/02/c-objects-part-1-basic-object-memory.html
  • 對于每一個(不是對象),如果其有虛函數(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) )

    class A; const std::type_info& ti1 = typeid(A); // 不能被復制 const std::type_info& ti2 = typeid(A);assert(&ti1 == &ti2); // 不保證 assert(ti1.hash_code() == ti2.hash_code()); // 保證 assert(std::type_index(ti1) == std::type_index(ti2)); // 保證// 注意 std::type_info.name 不具有一致性(同一類型在不同編譯器下的name可能不一樣) // std::type_info 不能被復制,而 std::type_index 可以被復制 // 基于以上,可以按照如下方式構建自定義類型的名字:std::unordered_map<std::type_index, std::string> type_names;type_names[std::type_index(typeid(int))] = "int"; type_names[std::type_index(typeid(double))] = "double"; type_names[std::type_index(typeid(A))] = "A"; type_names[std::type_index(typeid(B))] = "B"; type_names[std::type_index(typeid(C))] = "C";

    一般來說,對于一個具有多態(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

    BaseClass * b= new DrivedClass; std::cerr << typeid(b).name() << std::endl; // 打印 name mangling 之后的類型名稱(sizeof 獲得類型的大小,typeid 返回 const typeinfo &), 需要 #include <typeinfo> if (dynamic_cast<DrivedClass*>(b)) // 用danamic_cast一下,為空即表示該基類指針指向的不是此派生類std::cerr << name << " is a Drived Class" << std::endl; elsestd::cerr << name << " is a Base Class" << std::endl;

    模板編程 — 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)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。