1

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

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

我将解析 json 并保存到对象。方法将提前知道并编译。我创建了这个简单的例子,我想知道我是否走对了路。

通过字符串添加和调用方法;男性和女性功能将作为对象的方法添加到对象中。

现在在对象中是属性性别,但后来我想对函数做同样的事情。通过方法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;
}
4

2 回答 2

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";
}
于 2014-01-01T04:35:22.250 回答
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;
}

请注意,我添加了propertieswhichmethods除了将名称映射到字符串而不是函数之外,它的作用相同。这取代了你的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;
}

PS我使用了std::标准类型名称的前缀版本,因为你不应该头文件中拥有using namespace std;或类似的名称。

于 2014-01-01T04:35:30.187 回答