我想在运行时创建对象,就像在JavaScript中一样:
person=new Object();
person.firstname="John";
我要解析json并保存到object。方法将事先知道并编译。 我创建了这个简单的例子,我想知道我是否采取了正确的方式。
按字符串添加和调用方法;函数male和female将作为对象的方法添加到object中。
现在对象是属性性别,但后来我想和函数做同样的事情。通过在Object中声明的方法setProperty
和getProperty
。这是一个好主意吗?
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=♂
new_method.method_name="method1";
object2->addMethod(new_method);
new_method.method_fn=♀
new_method.method_name="method2";
object2->addMethod(new_method);
object1->callMethod("method1","");
object2->callMethod("method2","");
return 0;
}
答案 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;
或类似的东西。