在运行时汇编自己的对象

时间:2013-04-30 14:06:44

标签: c++ json object

我想在运行时创建对象,就像在JavaScript中一样:

person=new Object();
person.firstname="John";

我要解析json并保存到object。方法将事先知道并编译。 我创建了这个简单的例子,我想知道我是否采取了正确的方式。

按字符串添加和调用方法;函数male和female将作为对象的方法添加到object中。

现在对象是属性性别,但后来我想和函数做同样的事情。通过在Object中声明的方法setPropertygetProperty。这是一个好主意吗?

typedef struct method
  {
  (void)(*method_fn)(Object * _this, string params);
  string method_name;
  } method;




 class Object{

 private:
      vector<method> methods;

 public:
     string gender;
     Object(){};
     ~Object(){};
     void addMethod(method metoda);
     bool callMethod(string methodName,string params);

 };


     void  male(Object *_this,string params) {
        _this->gender="Male";
    }

    void female(Object* _this,string params) {
        _this->gender="Female";
    }





 void Object::addMethod(method metoda)
        {
        methods.push_back(metoda);
        }


 bool Object::callMethod(string methodName,string params){

         for(unsigned int i=0;i<methods.size();i++)
            {
                if(methods[i].method_name.compare(methodName)==0)
                    {
                     (*(methods[i].method_fn))(this,params);
                    return true;
                    }
            }
         return false;
     }

使用,这是工作。

int _tmain(int argc, _TCHAR* argv[])
{

    Object *object1 = new Object();
    Object *object2 = new Object();


    method new_method;

    new_method.method_fn=&male;
    new_method.method_name="method1";


    object2->addMethod(new_method);


    new_method.method_fn=&female;
    new_method.method_name="method2";

    object2->addMethod(new_method);


    object1->callMethod("method1","");
    object2->callMethod("method2","");

    return 0;
}

2 个答案:

答案 0 :(得分:0)

这基本上没问题。您已为方法及其关联名称创建了动态容器。这就像动态语言在幕后所做的那样。

你可以做些什么来改进它是使用哈希映射,以获得更快的速度。例如:

typedef void (*Method)(Object& _this, const string& params);
typedef std::unordered_map<string, Method> NameToMethodMap;
typedef std::unordered_map<string, string> NameToValueMap;

class Object {
private:
    NameToMethodMap methods;

public:
    NameToValueMap attributes;

    void addMethod(const std::string& name, Method& method) {
        // TODO: check that name isn't in there first
        methods[name] = method;
    }
};

int main() {
    Object o;

    o.attributes["gender"] = "male";
}

答案 1 :(得分:0)

最好使用map并使用引用:

class Object {
public:
    Object() {}
    ~Object() {}
    typedef void (*Method)(Object& _this, const std::string& params);
    void setMethod(const std::string& name, Method fn) { methods[name] = fn; }
    bool callMethod(const std::string& name, const std::string& params);

private:
    std::map<std::string, Method> methods;
    std::map<std::string, std::string> properties;
};

bool Object::callMethod(const std::string& name, const std::string& params)
{
    // Look for it.
    // Note: in C++11, you can do this instead:
    //     auto methodIter = methods.find(name);
    std::map<std::string, Method>::iterator methodIter = methods.find(name);

    if(methodIter == methods.end())
        return false;

    // Found it.
    (*(methodIter->second))(*this, params);
    return true;
}

请注意,我添加了properties,它与methods的功能相同,只是它将名称映射到字符串而不是函数。这取代了您的string gender;内容。

无论如何,只需对主函数进行一些小改动,就不需要方法结构了:

int _tmain(int argc, _TCHAR* argv[])
{

    Object *object1 = new Object();
    Object *object2 = new Object();

    object1->addMethod("method1", &male);
    object2->addMethod("method2", &female);

    object1->callMethod("method1", "");
    object2->callMethod("method2", "");

    return 0;
}

P.S。我使用了标准类型名称的std::前缀versiojns,因为你应该从不在头文件中有using namespace std;或类似的东西。