c++ - 如何通过 C++ 中的另一种通用方式访问类的 getter 和 setter 方法
问题描述
我希望能够通过另一个类分配和/或检索对象的值,我可以在其中声明我想访问哪些属性、它们的类型、访问私有属性值的方法和分配方法价值。
我想将属性名称和操作值的方法存储在哈希中,这样我可以使用其他实体的类值的通用形式,但我不知道是否可能(我想是这样),我不知道该怎么做。
下面的代码不起作用,它是基于我为实现解决方案所做的尝试。错误之一是:
error: no matching function for call to 'Test<unsigned int>::Test(C&, const char [2], unsigned int (C::*)() const, void (C::*)(unsigned int))'
auto t1 = new Test<unsigned int>(c, "a", &C::getA, &C::setA);
在代码片段下方
#include <string>
#include <map>
class C {
public:
unsigned int getA() const {
return a;
}
void setA(unsigned int value) {
C::a = value;
}
const std::string &getB() {
return b;
}
void setB(const std::string &value) {
C::b = value;
}
private:
unsigned int a;
std::string b;
};
template<typename T>
class Test {
public:
Test(T t, const std::string attribute, const T (*getter)(), void (*setter)(T)) : t(t), attribute(attribute),
getter(getter), setter(setter) {}
const std::string &getAttribute() const {
return attribute;
}
private:
T t;
std::string attribute;
const T (*getter)();
void (*setter)(T t);
};
int main(int argc, char **argv) {
C c;
auto t1 = new Test<unsigned int>(c, "a", &C::getA, &C::setA);
auto t2 = new Test<std::string>(c, "b", &C::getB, &C::setB);
std::map<std::string, std::string *> map;
map.insert({t1.getAttribute, t1});
map.insert({t2.getAttribute, t2});
}
所以基本上我有两个问题,可以这样做吗?如果是这样,如何?
例如,在这种情况下,如果我需要检索“a”(变量)t1 的值,我想转到地图并使用测试类 getter 的函数指针。
基于此,我将为 json 等实现解析器功能。
解决方案
我做过类似的事情;我有许多变量(不同类型),我想通过一个界面进行修改。我传递了一个字符串,我的班级将把它翻译成一个值来分配给连接的变量。
我首先创建一个带有虚函数的类:
struct param_assign_base
{
virtual void assign(void* param, const char* value) = 0;
};
// Declare the concrete class.
template<typename p_type>
struct param_assign;
然后我为此创建专门的实例,例如用于bool
类型变量:
template<>
struct param_assign<bool> : param_assign_base
{
void assign(void* param, const char* value)
{
*static_cast<bool*>(param) = extract_bool(value);
}
bool extract_bool(const char* value)
{
// make a return value that will be assigned to the connected variable.
}
};
然后我填充一张地图:
using param_map_type = std::map<
std::string,
std::pair<void*, params::param_assign_base*>>;
param_map_type populate()
{
param_map_type param_map;
param_map["a"] = std::make_pair(&a, new param_assign<bool>);
param_map["b"] = std::make_pair(&b, new param_assign<char*>);
param_map["c"] = std::make_pair(&c, new param_assign<int>);
// a more proper design wouldn't use new, it would
// use std::make_unique to avoid memory leaks.
}
然后我使用构造param_map
变量来分配变量,例如:
param_map["a"].second->assign(param_map["a"].first, value_to_assign);
上面的行也可以放在一个函数中,这样你就可以避免重复param_map["a"]
。
这种设计的缺点是您将无法访问该变量,除非您可以在访问时显式转换其类型param_map["a"]
,因为在这种情况下它只是一个 void 指针。使用 map 时,每个条目都需要具有相同的类型,因此 map 无法区分类型。
推荐阅读
- c++ - Tensorflow 默认如何使用 CPU 内核?
- stm32 - MPU6050 在地址 0x68 上没有响应,但出现在 I2C 扫描地址中
- c# - 使用 PostMessage 模拟鼠标点击
- python-3.x - 如果循环在不需要时重复自身
- excel - 防止小数的 VBA 输入框
- javascript - javascript网页未在前台模式下接收通知,尽管在后台接收(仅数据消息)
- sql - 在 SQL Server 中的 select concat 语句中包含引号
- javascript - 尽管有箭头功能,但在 axios catch 块中未定义“this”
- python - 如何在python中为计数和比例创建聚合?
- vue.js - 返回状态变量的计算属性不是反应性的