C++ 通过名称获取指向数据成员的指针
假设我的类有一个整数数据成员:C++ 通过名称获取指向数据成员的指针,c++,C++,假设我的类有一个整数数据成员: class MyClass { public: MyClass(); private: int my_int; } 现在在构造之后,我希望接收一个数据类型、一个名称和一个值,全部编码为字符串: public MyClass(string type, string name, string value) { ... } 并根据类型和名称,将该值分配给构造中的数据成员。类似于: public MyClass(string type, strin
class MyClass {
public:
MyClass();
private:
int my_int;
}
现在在构造之后,我希望接收一个数据类型、一个名称和一个值,全部编码为字符串:
public MyClass(string type, string name, string value) { ... }
并根据类型和名称,将该值分配给构造中的数据成员。类似于:
public MyClass(string type, string name, string value)
{
this->parse(type, name, value);
}
private parse(string type_, string name_, string value_)
{
if (type_=="int")
{
int* int_ = getDataMember(name_);
(*int_)=atoi(value_);
}
else ....
}
所以现在当我声明MyClass c(“int”,“my_int”,“5”)
时,c将被初始化,其my_int
数据成员的值设置为5
问题是我不知道如何实现getDataMember(字符串名)。但是它显然会返回一个指向它的数据成员的名称:“名称”。虽然这不是C++应该如何使用的,但它不是完全不可能的。
#包括
#包括
类MyClass{
公众:
MyClass(常量标准::字符串和类型,常量标准::字符串和名称,常量标准::字符串和值);
私人:
void解析(const std::string和type、const std::string和name、const std::string和value);
模板
T*getDataMember(const std::string和name);
int my_int;
加倍我的双倍;
char my_char;
std::map members;//字符串到成员内存位置的映射
};
MyClass::MyClass(常量标准::字符串和类型,常量标准::字符串和名称,常量标准::字符串和值)
{
//成员名单必须硬编码
成员[“my_int”]=重新解释演员阵容(&my_int);
成员[“我的替身”]=重新解释演员阵容(和我的替身);
成员[“my_char”]=重新解释演员阵容(&my_char);
此->解析(类型、名称、值);
}
模板
T*MyClass::getDataMember(常量std::字符串和名称){
return reinterpret_cast(members[name]);//将需要处理无效的名称
}
void MyClass::parse(const std::string和type,const std::string和name,const std::string和value)
{
如果(类型=“int”)
{
int*int\=getDataMember(名称);
(*int_uu)=atoi(value_u.c_ustr());
}
}
内部主(空){
MyClass c(“int”、“my_int”、“5”);
返回0;
}
其思想是保留一个映射
,以引用字符串
到成员地址。使用字符串
访问地图将返回与该字符串
对应的成员地址。但是,当新成员被引入到该类时,必须对该映射进行硬编码。另外,getDataMember
函数必须处理向类中传递无效名称的情况
效率低下
string
比较基本上很慢。比较发生了
将成员插入地图时
通过parse
函数尝试识别类型,以及何时识别
您可以在地图中搜索正确的键
摆脱硬编码的可能方法
假设有一种无需硬编码即可填充地图的方法。这需要知道类中存在哪些数据成员。由于C++中没有这样的功能,我们必须解析文件,或者至少包含包含该类的文件的一部分。但是,我们需要在编译文件之前完成此操作。这给我们留下了两个选择:
在编译时执行,这涉及到使用预处理器指令。不幸的是,我不知道如何利用预处理器指令来实现这一点
编写一个外部可执行程序,用于解析项目/工作区中的文件,以标识类的数据成员,并继续在类的构造函数中追加成员映射的填充。i、 e.通过外部可执行文件自动化地图填充过程。然后,我们可以确保每当通过预构建事件构建项目时,始终运行此外部可执行文件
结论
我认为最好是找到另一种方法来解决你正在试图解决的问题,或者使用另一种语言,因为它看起来不是C++的。
考虑你真正的问题是什么
我相信您正在寻找的解决方案称为反序列化
class-MyClass{
公众:
void反序列化(XMLParser-xml);
私人:
int my_int;
加倍我的双倍;
char my_char;
};
void MyClass::反序列化(XMLParser xml){
while(xml.ReadLine()!=“MEMBERS”);//将xml解析器前进到指定成员的行
//继续按顺序反序列化成员
//这要求文件以正确的顺序列出成员
my_int=atoi(xml.ReadLine().c_str());
my_double=atof(xml.ReadLine().c_str());
my_char=atoi(xml.ReadLine().c_str());
}
> > 虽然这不是C++应该如何使用,但也不是完全不可能。
#包括
#包括
类MyClass{
公众:
MyClass(常量标准::字符串和类型,常量标准::字符串和名称,常量标准::字符串和值);
私人:
void解析(const std::string和type、const std::string和name、const std::string和value);
模板
T*getDataMember(const std::string和name);
int my_int;
加倍我的双倍;
char my_char;
std::map members;//字符串到成员内存位置的映射
};
MyClass::MyClass(常量标准::字符串和类型,常量标准::字符串和名称,常量标准::字符串和值)
{
//成员名单必须硬编码
成员[“my_int”]=重新解释演员阵容(&my_int);
成员[“我的替身”]=重新解释演员阵容(和我的替身);
成员[“my_char”]=重新解释演员阵容(&my_char);
此->解析(类型、名称、值);
}
模板
T*MyClass::getDataMember(常量std::字符串和名称){
return reinterpret_cast(members[name]);//将需要处理无效的名称
}
void MyClass::parse(const std::string和type,const std::string和name,const std::string和value)
{
如果(类型=“int”)
{
int*int\=getDataMember(名称);
(*int_uu)=atoi(value_u.c_ustr());
}
}
内部主(空){
MyClass c(“int”、“my_int”、“5”);
返回0;
}
其思想是保留一个映射
,以引用字符串
到成员地址。使用访问地图