青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

cpp小菜園

簡(jiǎn)單即是複雜

  C++博客 :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
  2 Posts :: 0 Stories :: 0 Comments :: 0 Trackbacks

常用鏈接

留言簿(3)

我參與的團(tuán)隊(duì)

搜索

  •  

最新評(píng)論

閱讀排行榜

評(píng)論排行榜


  最近(其實(shí)也有一段時(shí)間了),在c++項(xiàng)目中需要用到類(lèi)似java的反射機(jī)制,時(shí)間也比較趕,只能周?chē)纯从袥](méi)有現(xiàn)成的庫(kù)可用了,找到的資料也不算少,但多數(shù)都是關(guān)于動(dòng)態(tài)創(chuàng)建類(lèi)的,有點(diǎn)像工廠模式,而我需要的,是把實(shí)體類(lèi)中的屬性反射出來(lái)。最后,找到了一個(gè)叫LibReflection的東西,雖然后來(lái)還是沒(méi)用上這個(gè),但是稍微看了一下代碼,還是有不少收獲,所以就在這里記錄下來(lái)了,當(dāng)做學(xué)習(xí),也當(dāng)做對(duì)這個(gè)庫(kù)的一個(gè)分析吧。
  LibReflection是屬性和函數(shù)反射都有實(shí)現(xiàn)的,而整個(gè)庫(kù)竟然就一個(gè)h文件,本人精力有限,只把屬性反射抽取出來(lái),相信離實(shí)際應(yīng)用也有距離,如果有人路過(guò)看到,請(qǐng)?bào)w諒別拍磚了。
  那么,首先看一下使用:

    TestClass inst;
    tat::tat_class *test_class = TestClass::get_class_ptr();
    std::map<std::string,tat::tat_field> field_map = test_class->get_fields();
    tat::tat_field test_vec_field = field_map.find("_vec_f")->second;
    std::vector<int> vec;
    test_vec_field.get(&inst,vec);
    vec.push_back(22);
    test_vec_field.set(&inst,vec);
    std::cout<<inst._vec_f[0]<<std::endl;

  TestClass類(lèi)先不給出,反正就是該類(lèi)有一個(gè)名字為“_vec_f”的屬性,類(lèi)型是std::vector<int>,然后這段代碼通過(guò)反射修改_vec_f的內(nèi)容。。至于tat_class和tat_field,相信熟悉java的人都能猜出是什么了。
  獲取及設(shè)置一個(gè)實(shí)例的成員變量的值不是難事,用一個(gè)宏就可以了:

#define _OFFSET_(_Obj_Ty,_Key)                                                    \
    ((unsigned long)(&((_Obj_Ty *)0)->_Key))

   這個(gè)宏應(yīng)該也不難理解,就是獲取成員變量相對(duì)實(shí)例指針的偏移值。而關(guān)鍵問(wèn)題是,如何通過(guò)變量名稱就能查找出這個(gè)偏移呢?如何在變量初始化的時(shí)候就能記錄下這個(gè)偏移呢?我們可以通過(guò)宏來(lái)聲明變量,那么聲明的時(shí)候就可以做一些事情了,但具體做些什么,還是沒(méi)頭緒。
  這個(gè)問(wèn)題自己思考了一段時(shí)間,無(wú)果。然后看了一下實(shí)現(xiàn),深感自己的基礎(chǔ)還沒(méi)過(guò)關(guān),其實(shí)說(shuō)白了就是兩個(gè)東西:構(gòu)造函數(shù)、靜態(tài)成員變量。
  我們的目標(biāo)是很明確的,要做到j(luò)ava的效果,結(jié)合上面那個(gè)宏,也不難想象出Class和Field類(lèi)的樣子(這里是tat_class和tat_field),tat_class無(wú)非就是保存了一個(gè)map,key是屬性的名稱,value是tat_field,至于tat_field就簡(jiǎn)單了,核心就是保存內(nèi)存的偏移值,再提供操作值的接口就可以了。
  先來(lái)看看tat_class:

    class tat_class
    {
    private:
        std::map<std::string,tat_field> _field_map;
        std::string _key;
    public:
        std::map<std::string,tat_field> get_fields()
        {
            return this->_field_map;
        }
        tat_field get_field(std::string key)
        {
            std::map<std::string,tat_field>::iterator itr = _field_map.find(key);
            return (*itr).second;
        }
        void add_field(const tat_field &field)
        {
            _field_map.insert(std::pair<std::string,tat_field>(field.get_key(),field));
        }
    };

  沒(méi)有什么理解上的難點(diǎn)吧。
  然后看看tat_field:

    class tat_field
    {
    private:
        unsigned long _offset;
        std::string _key;
    public:
        tat_field(unsigned long offset,std::string key):_offset(offset),_key(key){}
        tat_field(const tat_field &field)
        {
            this->_offset = field._offset;
            this->_key = field._key;
        }
    public:
        template<typename _Obj_Ty,typename _Value_Ty>
        void get(_Obj_Ty *obj,_Value_Ty &value)
        {
            value = *((_Value_Ty *)((unsigned char *)obj + _offset));
        }
        template<typename _Obj_Ty,typename _Value_Ty>
        void set(_Obj_Ty *obj,const _Value_Ty &value)
        {
            *((_Value_Ty *)((unsigned char *)obj + _offset)) = value;
        }
        std::string get_key() const
        {
            return this->_key;
        }
    };

  變量值的get和set函數(shù)使用了模板,這是為了使用的時(shí)候能作簡(jiǎn)單的類(lèi)型推斷。
  然后就是重點(diǎn)了,如何在聲明類(lèi)的時(shí)候就把tat_class注入呢?如前面說(shuō)的,靜態(tài)成員變量:

#define CLASS_REGISTER(_Obj_Ty)                                                    \
public:                                                                            \
    static tat::tat_class * get_class_ptr()                                        \
    {                                                                            \
        static tat::tat_class __class_##_Obj_Key##__;                            \
        return &__class_##_Obj_Key##__;                                            \
    }

  這個(gè)宏做了兩件事:第一,聲明靜態(tài)函數(shù)get_class_ptr(),返回tat_class類(lèi)型,第二,當(dāng)然就是初始化tat_class了,因?yàn)橥瑯邮庆o態(tài),所以不同的實(shí)例就共享了。
  接下來(lái)是另一個(gè)重點(diǎn),如何在聲明成員變量的時(shí)候把tat_field注入到tat_class中,還是用宏解決:

#define FIELD_REGISTER(_Access,_Field_Ty,_Field_Key,_Obj_Ty)                    \
_Access:                                                                        \
    _Field_Ty _Field_Key;                                                        \
private:                                                                        \
    class __field_register_##_Field_Key##__                                        \
    {                                                                            \
    public:                                                                        \
        __field_register_##_Field_Key##__()                                        \
        {                                                                        \
            static tat::__field_register__ reg_##_Field_Key(                    \
                _Obj_Ty::get_class_ptr(),                                        \
                _OFFSET_(_Obj_Ty,_Field_Key),                                    \
                #_Field_Key);                                                    \
        }                                                                        \
    }_Field_Key##_register;

  分析這個(gè)宏,首先當(dāng)然是聲明變量了;然后就是一個(gè)神秘的類(lèi):__field_register_##_Field_Key##__,這個(gè)類(lèi)就只有一個(gè)構(gòu)造函數(shù),構(gòu)造函數(shù)里面又是一個(gè)靜態(tài)變量,類(lèi)型是tat::__field_register__,可以想象得到,既然tat_class已經(jīng)可以聲明出來(lái)了,tat_field自然也沒(méi)有難度,但聲明是不足夠的,還需要放到tat_class的map里面才算完成,在聲明一個(gè)變量的時(shí)候,能做事的地方,我只能想到是構(gòu)造函數(shù)了,所以就有了剛剛那個(gè)神秘的類(lèi),那個(gè)類(lèi)的唯一作用就是其構(gòu)造函數(shù),而構(gòu)造函數(shù)里面聲明靜態(tài)變量,則是防止多次實(shí)例化類(lèi)帶來(lái)的冗余數(shù)據(jù),確保一個(gè)成員變量只有一個(gè)tat_field;
  剩下的關(guān)鍵,就是tat::__field_register__了:

    class __field_register__
    {
    public:
        __field_register__(tat_class *class_ptr,unsigned long offset,std::string key)
        {
            tat_field field(offset,key);
            class_ptr->add_field(field);
        }
    };

  沒(méi)有什么神秘的地方,這個(gè)東西就這么完成了。
  差點(diǎn)忘了TestClass的聲明:

#include "fieldref.h"

class TestClass
{
public:
    TestClass(void);
    ~TestClass(void);

    CLASS_REGISTER(TestClass)
    FIELD_REGISTER(public,long,_long_f,TestClass)
    FIELD_REGISTER(public,int,_int_f,TestClass)
    FIELD_REGISTER(public,std::string,_str_f,TestClass)
    FIELD_REGISTER(public,std::vector<int>,_vec_f,TestClass)
};

  好吧,如果說(shuō)到實(shí)際應(yīng)用的問(wèn)題,灑家確實(shí)沒(méi)有考慮太多,反正測(cè)試函數(shù)能跑,結(jié)果也對(duì)了,灑家也就滿足了,就單純的當(dāng)做是一次實(shí)驗(yàn),或者是學(xué)習(xí)而已。
posted on 2012-04-25 13:18 閱讀(4073) 評(píng)論(0)  編輯 收藏 引用

只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            91久久久精品| 亚洲大胆美女视频| 国产精品视频久久久| 欧美精品亚洲精品| 欧美成人第一页| 欧美另类69精品久久久久9999| 亚洲欧美文学| 午夜精品免费视频| 校园春色国产精品| 久久久久在线| 美玉足脚交一区二区三区图片| 久久久久久免费| 噜噜噜91成人网| 欧美高清在线一区二区| 欧美日韩国产色综合一二三四 | 日韩视频精品在线观看| 一本色道久久综合亚洲精品高清 | 久久综合导航| 亚洲免费在线观看| 欧美一二区视频| 免费永久网站黄欧美| 欧美日韩一区二区在线播放| 国产伦精品一区二区三区视频黑人| 国产欧美日韩免费看aⅴ视频| 国产日韩一区二区三区| 亚洲高清不卡在线| 亚洲综合三区| 你懂的国产精品| 亚洲免费高清| 久久精品欧美| 亚洲国产成人av在线 | 校园春色国产精品| 欧美精品在线免费播放| 好吊妞**欧美| 亚洲欧美日韩另类精品一区二区三区| 久久米奇亚洲| 一区二区三区欧美在线| 蜜臀av性久久久久蜜臀aⅴ四虎 | 国产日韩av一区二区| 欧美性大战久久久久久久| 欧美欧美天天天天操| 国内偷自视频区视频综合| 亚洲国产成人不卡| 亚洲国产日韩欧美| 性欧美8khd高清极品| 亚洲破处大片| 美女黄毛**国产精品啪啪| 国产视频在线观看一区二区三区| 亚洲最新视频在线播放| 亚洲高清自拍| 可以免费看不卡的av网站| 国产欧美韩日| 香蕉乱码成人久久天堂爱免费| 亚洲日本欧美在线| 久久精品一区二区三区不卡牛牛 | 在线精品国产欧美| 午夜久久福利| 亚洲天堂激情| 国产精品久久久久三级| 亚洲免费在线观看| 最新中文字幕一区二区三区| 免费成人毛片| 亚洲精品久久在线| 亚洲欧洲精品一区二区三区| 久久九九久精品国产免费直播| 国产精品嫩草99av在线| 夜夜嗨网站十八久久| 亚洲韩国青草视频| 欧美韩日亚洲| 久久免费高清视频| 亚洲尤物在线| 另类天堂视频在线观看| 亚洲综合99| 国产亚洲女人久久久久毛片| 香蕉久久夜色精品| 久久精品国产亚洲一区二区三区| 国产美女一区二区| 久久深夜福利免费观看| 性欧美在线看片a免费观看| 国产在线成人| 久久精品九九| 老司机67194精品线观看| 亚洲福利在线看| 亚洲精品国产系列| 欧美日韩视频第一区| 欧美一区二区三区四区视频 | 一区二区欧美激情| 亚洲日本中文| 久久精品成人一区二区三区蜜臀| 国产精品一区二区你懂得| 久久久亚洲欧洲日产国码αv | 国产精品成人aaaaa网站| 国内成人自拍视频| 国产精品国产三级国产aⅴ无密码| 亚洲美女诱惑| 在线观看不卡| 亚洲欧美日韩精品久久奇米色影视| 欧美jizz19性欧美| 久久久精品一区二区三区| 亚洲免费视频在线观看| 久久国产一区二区三区| 老司机亚洲精品| 欧美视频免费看| 精品av久久707| 日韩一二三在线视频播| 亚洲一区区二区| 久久亚洲综合| 国产一区再线| 久久激情五月婷婷| 亚洲国产色一区| 中文在线不卡| 欧美香蕉大胸在线视频观看| 精品av久久707| 久久久久久日产精品| 国产精品99一区二区| 亚洲精品中文字幕女同| 欧美成人在线免费视频| 久久久久国产成人精品亚洲午夜| 国产精品xxxxx| 亚洲精品少妇| 亚洲国产影院| 欧美人在线观看| 一本色道久久综合一区| 欧美永久精品| 国产精品欧美日韩久久| 亚洲一区二区三区在线视频| 日韩亚洲精品视频| 欧美视频中文在线看| 亚洲一区二区免费看| 一区二区三区精品久久久| 国产精品亚洲综合| 亚洲性色视频| 国产亚洲精品久久久| 久久久久久九九九九| 久久免费精品视频| 亚洲二区视频在线| 亚洲高清视频一区二区| 欧美涩涩网站| 欧美日韩国产精品一区二区亚洲| 亚洲伦理网站| 亚洲人成在线免费观看| 国产精品v欧美精品v日韩精品 | 久久久999精品免费| 欧美国产丝袜视频| 久久精品国产99精品国产亚洲性色| 国产综合色产| 久久不见久久见免费视频1| 亚洲欧美国产高清va在线播| 国产精品夜夜夜| 极品尤物久久久av免费看| 亚洲欧美一区二区精品久久久| 国产亚洲欧美一区二区| 美女视频黄免费的久久| 久久亚洲精选| 99热在线精品观看| 中文亚洲欧美| 在线观看日韩一区| 亚洲日本电影| 国产精品亚洲综合色区韩国| 狂野欧美性猛交xxxx巴西| 免费看黄裸体一级大秀欧美| 伊人久久婷婷色综合98网| 亚洲乱码日产精品bd| 国产免费一区二区三区香蕉精| 欧美xxxx在线观看| 欧美三区在线视频| 欧美一区二区在线免费观看| 亚洲国产天堂久久综合| 亚洲视频一区二区| 亚洲国产美女精品久久久久∴| 一本色道久久综合| 1769国产精品| 一区二区三区 在线观看视| 欧美日韩国产一区| 久久精品国产亚洲一区二区| 欧美高清在线一区| 久久久久国内| 午夜精品av| 亚洲国产一区在线观看| 亚洲一区综合| 亚洲美女av电影| 久久亚洲图片| 久久精品卡一| 国产精品网站在线播放| 最近中文字幕mv在线一区二区三区四区 | 欧美日韩少妇| 免费视频一区| 久久中文字幕一区二区三区| 亚洲视频精选在线| 亚洲国产乱码最新视频| 欧美在线3区| 久久精品一区蜜桃臀影院| 欧美日韩午夜剧场| 亚洲日本久久| 99xxxx成人网| 亚洲一区三区视频在线观看| 国产嫩草影院久久久久 | 欧美成人一区二区| 久久久人成影片一区二区三区| 国产精品嫩草久久久久|