如何解决c++ - 如何使用字符串或整数作为键动态注册对象,并使用C++中的键存储、访问它?
我想用 C++ 设计一个数据仪表板框架,要求如下:
- 客户可以使用键(字符串或整数都可以接受)将数据类型注册到仪表板
- 客户端可以存储/访问具有已知数据类型和密钥的对象
下面的示例代码演示了我想如何使用它
// data.hpp
struct DataA
{
DataA();
int a;
};
struct DataF
{
DataF();
float f;
};
// data.cpp
static DataA s_da;
static DataF s_df;
DataA::DataA()
{
if(!Dashboard::Register("A",s_da)) {
cerr << "unable to register DataA,key is used";
}
}
DataF::DataF()
{
if(!Dashboard::Register("F",s_df)) {
cerr << "unable to register DataF,key is used";
}
}
// main.cpp
int main ()
{
DataA da;
da.a = 123;
Dashboard::Set("A",da);
DataF df;
df.f = 3.14;
Dashboard::Set("F",df);
cout << ((DataA)Dashboard::Get("A")).a << endl; // 123
cout << ((DataF)Dashboard::Get("F")).f << endl; // 3.14
return 0;
}
但是,我想不出实现 Dashboard
类来提供接口的任何想法。
如何动态注册具有给定数据类型和键的对象?是否有任何设计模式可以满足此要求?
解决方法
我构建了类似您在我的团队中描述的东西,作为用于跨应用程序路由消息的库的内部。
如果您坚持使用 C++11(例如 std::any
或 std::variant
不可用),您可以有一个空的虚拟基类类型,如下所示:
class BaseValue
{
public:
BaseValue() {};
virtual ~BaseValue() {}; // need one virtual method for dynamic_cast
};
还有一个派生的模板类,如下所示:
template <typename T>
class Value : public BaseValue
{
public:
Value(const T& t) : _t(t)
{}
T _t;
};
那么你的数据结构是这样的。它是字符串到 BaseValue 指针之间的映射
unordered_map<string,BaseValue*> dashboard;
我们将使用派生自 BaseValue 的模板类 Value 将数据走私到上面的地图中。
插入仪表盘是这样的:
template <typename T>
void insert(const string& name,const T& t)
{
Value<T>* pT = new Value<T>(t);
dashboard.insert(name,pT);
}
获取是这样的。对于“未找到”场景,有多种方法可以构建“get”调用。
template<typename T>
T& get(const string& name,const T& default = {})
{
auto itor = dashboard.find(name);
if (itor != dashboard.end())
{
BaseValue* pBaseValue = itor->second;
T* pValue = dynamic_cast<T*>(pBaseValue);
if (pValue)
{
return pValue->_t;
}
}
return default; // you could also throw an exception
}
示例插入:
DataA da;
da.a = 123;
insert("a",da);
获取示例:
DataA& da = get<A>("a");
您可以对上述内容进行很多改进。首先,您可以将所有辅助函数转换为一个类。在内部使用 shared_ptr 而不是原始指针。等等...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。