按名称获取指向数据成员的指针
Obtain a pointer to a data member by its name
假设我的类有一个整数数据成员:
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(字符串名称)。但它显然会返回一个指向其名称"name"的数据成员的指针。
虽然这不是C++应该使用的方式,但并非完全不可能。
#include <string>
#include <map>
class MyClass {
public:
MyClass(const std::string& type, const std::string& name, const std::string& value);
private:
void parse(const std::string& type_, const std::string& name_, const std::string& value_);
template <typename T>
T* getDataMember(const std::string& name);
int my_int;
double my_double;
char my_char;
std::map<std::string, char*> members; //Map of strings to member memory locations
};
MyClass::MyClass(const std::string& type, const std::string& name, const std::string& value)
{
//List of members will have to be hardcoded
members["my_int"] = reinterpret_cast<char*>(&my_int);
members["my_double"] = reinterpret_cast<char*>(&my_double);
members["my_char"] = reinterpret_cast<char*>(&my_char);
this->parse(type, name, value);
}
template <typename T>
T* MyClass::getDataMember(const std::string& name) {
return reinterpret_cast<T*>(members[name]); //Will need to handle invalid names
}
void MyClass::parse(const std::string& type_, const std::string& name_, const std::string& value_)
{
if (type_=="int")
{
int* int_ = getDataMember<int>(name_);
(*int_)=atoi(value_.c_str());
}
}
int main(void) {
MyClass c("int","my_int","5");
return 0;
}
这个想法是保留一个map
来引用string
成员地址。使用 string
访问映射将返回与该string
对应的成员的地址。但是,当将新成员引入类时,必须对此map
进行硬编码。此外,getDataMember
函数必须处理将无效名称传递到类中的情况。
效率 低下
string
比较基本上是缓慢的。进行比较发生当您将成员插入map
时,当您要去通过您的parse
函数尝试识别类型,以及何时您在地图上搜索正确的键。
摆脱硬编码的可能方法
假设有一种方法可以在不进行硬编码的情况下填充地图。这将涉及了解类中存在哪些数据成员。由于C++中似乎没有这样的功能,因此我们必须解析文件,或者至少解析包含类的文件部分。但是,我们需要在编译文件之前完成此操作。这给我们留下了 2 个选择:
- 在编译时执行此操作,这涉及使用预处理器指令。不幸的是,我不知道任何利用预处理器指令来做到这一点的方法。
- 对解析项目/工作区中的文件的外部可执行文件进行编程,以标识类的数据成员,并继续在类的构造函数中追加成员映射的填充。 即通过外部可执行文件自动执行地图填充过程。然后,我们可以确保每当通过预构建事件构建项目时,始终运行此外部可执行文件。
结论
我认为最好找到另一种方法来解决问题,或者使用完全不同的语言,因为它似乎不是为此而构建C++。
考虑您的真正问题是什么
我相信您正在寻找的解决方案称为反序列化。
class MyClass {
public:
void Deserialize(XMLParser xml);
private:
int my_int;
double my_double;
char my_char;
};
void MyClass::Deserialize(XMLParser xml) {
while(xml.ReadLine() != "MEMBERS"); //Advances the XML parser to the line that specifies the members
//Proceed to deserialize the members in order
//This requires the file to list the members in the correct order
my_int = atoi(xml.ReadLine().c_str());
my_double = atof(xml.ReadLine().c_str());
my_char = atoi(xml.ReadLine().c_str());
}
相关文章:
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 使用指针访问数组中的对象数据成员
- 共享 C++ 的数据成员指针
- C++数据成员:值与指针
- 如何使用数据成员填充派生类的对象到基类的指针数组中
- 如何在C++中使用类对象访问指针数据成员
- 将指向数据成员的指针传递给 std::invoke 时有哪些用例和有用性?
- 通过指针算法访问结构数据成员
- 如何强制实施有关指针数据成员的常量正确性
- 类数据成员指针的非类型模板参数包无法使用 gcc 编译
- constexpr 偏移量,带有指向成员数据的指针
- 指向未由对象地址初始化的对象的指针如何将值分配给类的数据成员
- 将数据成员的指针传递给基类构造函数是否安全?
- 虚拟指针大小因类数据成员而异
- "new"不会将内存分配给作为类的数据成员的指针
- 关于Lambdas,转换以功能指针以及私人数据成员的可见性
- 向上转换指向数据成员及其多态行为的指针
- 指向数据成员转换的 Constexpr 指针
- 关于C++中指向数据成员的指针的一些混淆
- C 细分故障访问类数据成员,而无需明确使用指针