首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用字符串或int作为键动态注册对象,并使用C++中的键存储、访问它?

如何使用字符串或int作为键动态注册对象,并使用C++中的键存储、访问它?
EN

Stack Overflow用户
提问于 2021-03-12 08:47:34
回答 1查看 60关注 0票数 0

我想用c++设计一个具有以下要求的数据仪表板框架:

acceptable)

  • clients客户端可以使用键(字符串或整数都是
  1. 客户机)将数据类型注册到仪表板上,可以使用已知的数据类型和键

存储/访问对象。

下面的示例代码演示如何使用它

代码语言:javascript
复制
// 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类来提供接口的任何想法。

如何使用给定的数据类型和键动态注册对象?是否有满足此需求的设计模式?

EN

回答 1

Stack Overflow用户

发布于 2021-03-12 18:15:09

我构建了类似您在我的团队中描述为一个库内部的东西,这个库用于在应用程序中路由消息。

如果您被困在C++11上(例如std::anystd::variant不可用),则可以有一个空的虚拟基类类型如下:

代码语言:javascript
复制
class BaseValue
{
public:
    BaseValue() {}; 
    virtual ~BaseValue() {};  // need one virtual method for dynamic_cast
};

以及派生的模板类,例如:

代码语言:javascript
复制
template <typename T>
class Value : public BaseValue
{
public:
    Value(const T& t) : _t(t)
    {}

    T _t;
};

那么您的数据结构是这样的。它是字符串到BaseValue指针之间的映射

代码语言:javascript
复制
unordered_map<string, BaseValue*> dashboard;

我们将通过使用从BaseValue派生的模板类值将数据走私到上面的映射中。

插入仪表板如下所示:

代码语言:javascript
复制
template <typename T>
void insert(const string& name, const T& t)
{
     Value<T>* pT = new Value<T>(t);
     dashboard.insert(name, pT);
}

抓取就像这样。对于“未找到”的场景,构建"get“调用有不同的方法。

代码语言:javascript
复制
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
}

示例插入:

代码语言:javascript
复制
DataA da;
da.a = 123;
insert("a", da);

示例提取:

代码语言:javascript
复制
DataA& da = get<A>("a");

你可以对上面的内容做很多改进。首先,您可以将所有助手函数转换为一个类。在内部使用shared_ptr而不是原始指针。等等。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66596763

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档