通过变量(字符串)调用obejct和方法

Call obejct and method via variable (string)

本文关键字:调用 obejct 方法 字符串 变量      更新时间:2023-10-16

首先,我已经在stackoverflow上搜索了1个多小时,但我真的不知道如何找到我想要的特定问题(我想已经有一些答案了)。我正试图通过变量(字符串)调用对象我的代码示例:

//class itself 
using namespace std   
class locations {
public:
    locations(int id, string name){  // constructor
        this->id= id;
        this->name=name;
    }
    int id= 0;
    string name = "";
};

和新对象:

locations home(1,"home");

我现在想要的是:

string obj = "home";
obj.id = 3;

string meth = "id";
home.meth = 3;

如果你有任何好的链接到其他问题,这将是有帮助的。也许它可以通过矢量以某种方式访问,但我对它不太了解

C++在设计时考虑到了强大的类型和编译时检查与优化。对于您想要的访问,没有内置的设施。

1) 动态查找对象:

C++不支持您所期望的语义:

 string obj = "home";  // create an object of type string.  
 obj.id = 3;           // access to member id of your object.

如果它是动态的,生成的代码将需要维护变量的范围(因为home对象在不同的范围中可能有不同的含义。

但幸运的是,您可以很容易地实现一个对象存储,在这个存储中,您可以在地图的帮助下注册对象及其名称:

map<string, locations> mystore;    // store of all my location variables 
mystore["home"] = locations(1,"home");   // copy a new object into the store
string obj = "home";
mystore[obj].id = 3;   // access object via its name.  

顺便说一句,如果locations::name只是按名称提供访问权限,那么在locations中就不再需要它了,因为映射无论如何都会将字符串链接到对象值。

2) 动态查找成员:

C++根本不支持你的语义:

string meth = "id";  // name of a member 
home.meth = 3;       // invalid:  because meth is not a member of home

C++不支持java和其他半编译或解释语言中的反射。如果你需要这样的东西,你需要仔细设计你的类来自己实现它。这将是相当困难的,因为每个成员都可以有自己的类型,而C++需要在编译时知道类型。

一种方法是将映射的使用(存储动态成员)与boost::variant的使用(在映射中存储可以具有不同类型值的对象)相结合。

但这并不容易,最重要的是,您必须自己管理不同类之间的任何继承逻辑。

C++不是这样做的,C++是一种面向对象、静态类型的值语义语言。所有这些都会影响设计,而你想要的设计似乎不适合静态类型语言。这是否会导致你改变设计,或者改变语言,取决于你自己。也就是说,如果你真的想在运行时映射对象和方法,可以模拟如下:

#include <iostream>
#include <string>
#include <map>
using namespace std;
struct Object;
typedef int (*funcptr)(Object*,int);
struct Object
{
  map<string,funcptr> funcs;
  map<string,int> data;
  int call(string name,int param) { return funcs[name](this,param); }
};
map<string,Object> allObjects;
Object& get(string name) { return allObjects[name]; }
//----------------------------------------------------------------------------------
int main()
{
  get("obj1").funcs["run"] = [](Object* self,int param) -> int { self->data["somename"] = param; return 0; };
  get("obj1").call("run",5);
  cout << get("obj1").data["somename"] << endl;
}

也就是说,不要这样做,将您的设计更改为真正适合C++优势的东西,即面向对象、静态类型、值语义。