如何优雅的写C++代码 Obotcha介绍(简单的反射实现二)

    Obotcha的反射基本已经都实现。目前能支持数据库,xml,json的ORM实现。

template<typename T>
void reflectTo(T obj)

template<typename T>
void importFrom(T value)

JsonValue目前提供如上两个接口,reflectTo是将json数据直接导入到class对象中。importFrom是将class对象数据直接转成json数据。接下来我们看以下reflectTo和importFrom的实现吧:

template<typename T>
    void reflectTo(T obj) {
        sp<_JsonValueIterator> iterator = this->getIterator();
        while(iterator->hasValue()) {
            String key = iterator->getTag();
            
            Field field = obj->getField(key);
            if(field == nullptr) {
                printf("key is %s \n",key->toChars());
                iterator->next();
                continue;
            }
            std::string name = field->getName()->getStdString();
            JsonValue jsonnode = iterator->getValue();

            switch(field->getType()) {
                case FieldTypeLong:{
                    String value = jsonnode->getString();
                    field->setValue(value->toBasicLong());
                    }
                    break;

                case FieldTypeInt: {
                        String value = jsonnode->getString();
                        field->setValue(value->toBasicInt());
                    }
                    break;

                case FieldTypeByte:{
                        String value = jsonnode->getString();
                        field->setValue(value->toBasicByte());
                    }
                    break;

                case FieldTypeBool:{
                        String value = jsonnode->getString();
                        field->setValue(value->toBasicBool());
                    }
                    break;

                case FieldTypeDouble:{
                        String value = jsonnode->getString();
                        field->setValue(value->toBasicDouble());
                    }
                    break;

                case FieldTypeFloat:{
                        String value = jsonnode->getString();
                        field->setValue(value->toBasicFloat());
                    }
                    break;

                case FieldTypeString:{
                        String value = jsonnode->getString();
                        field->setValue(value);
                    }
                    break;

                case FieldTypeUint8:{
                        String value = jsonnode->getString();
                        field->setValue(value->toBasicUint8());
                    }
                    break;

                case FieldTypeUint16:{
                        String value = jsonnode->getString();
                        field->setValue(value->toBasicUint16());
                    }
                    break;

                case FieldTypeUint32:{
                        String value = jsonnode->getString();
                        field->setValue(value->toBasicUint32());
                    }
                    break;

                case FieldTypeUint64:{
                        String value = jsonnode->getString();
                        field->setValue(value->toBasicUint64());
                    }
                    break;
                        
                case FieldTypeObject: {
                        //create Objectt
                        printf("createobj name is %s\n",name.c_str());
                        field->createObject();
                        auto reflectValue = field->getObjectValue();
                        if(reflectValue != nullptr) {
                            printf("create obj not null \n");
                        } else {
                            printf("create obj null \n");
                        }
                        jsonnode->reflectTo(reflectValue);
                    }
                    break;

                case FieldTypeArrayList:
                    jsonnode->reflectToArrayList(obj,field->getName());
                    break;
            }

            iterator->next();
        }
    }

主要就是通过json节点的name去查找Class对应的成员变量的field。接下来再通过这个field去设定数据。和Java的反射有点类似。这里主要留意两点:

1.如果成员变量不是简单的数据类型,而且一个struct或者class,那反射得到的都是Object类(主要是getObjectValue虽然用了auto返回值,但是C++14/11/17编译的时候都规定,同一个函数的auto返回类型必须一致,所以只能返回Object类)。

2.成员变量是ArrayList的反射比较复杂,因为通过getObjectValue得到的数据都是Object,已经无法获取ArrayList<T>中的T类型,后续想创建T的实例基本就不可能了。所以目前的方法是Field中有一个createListItemObject 函数,这个函数直接来创建T的实例,而且创建的同时,这个实例会自动加到Field对应的ArrayList中去。所以如果要反射ArrayList,需要编写类似下面的代码:

template<typename T>
    void reflectToArrayList(T obj,String name) {
        Field field = obj->getField(name);
        field->createObject(); //创建ArrayList实例
        int size = this->size();
        for(int index = 0;index<size;index++) {
            //创建ArrayList中的Item实例,同时该实例会自动添加到ArrayList
            auto vv = field->createListItemObject();
            JsonValue value = this->getValueAt(index);
            value->reflectTo(vv);
        }
    }

反射相关的代码如下:

https://github.com/wangsun1983/Obotcha/blob/master/lang/include/Reflect.hpp

基本思路都是通过宏/模板+tuple来实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值