簡體   English   中英

如何使用 string 或 int 作為 key 動態注冊 object,並使用 C++ 中的 key 存儲、訪問它?

[英]How to register an object using string or int as key dynamically, and store, access it with the key in C++?

我想用 c++ 設計一個數據儀表板框架,具有以下要求:

  1. 客戶端可以使用鍵將數據類型注冊到儀表板(字符串或 integer 都可以接受)
  2. 客戶端可以使用已知的數據類型和密鑰存儲/訪問 object

下面的示例代碼演示了我想如何使用它

// 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 class 以提供接口。

如何使用給定的數據類型和鍵動態注冊 object? 是否有任何設計模式可以滿足此要求?

我在我的團隊中構建了您所描述的東西,作為用於跨應用程序路由消息的庫的內部。

如果您卡在 C++11 上(這樣std::anystd::variant不可用),您可能有一個空的虛擬基礎 class 類型,如下所示:

class BaseValue
{
public:
    BaseValue() {}; 
    virtual ~BaseValue() {};  // need one virtual method for dynamic_cast
};

以及派生模板 class 如下:

template <typename T>
class Value : public BaseValue
{
public:
    Value(const T& t) : _t(t)
    {}

    T _t;
};

那么你的數據結構是這樣的。 這是字符串到 BaseValue 指針之間的 map

unordered_map<string, BaseValue*> dashboard;

我們將使用從 BaseValue 派生的模板 class 值將數據走私到上面的 map 中。

插入儀表板是這樣的:

template <typename T>
void insert(const string& name, const T& t)
{
     Value<T>* pT = new Value<T>(t);
     dashboard.insert(name, pT);
}

抓取是這樣的。 對於“未找到”場景,有不同的方式來構建“獲取”調用。

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");

您可以對上述內容進行很多改進。 對於初學者,您可以將所有輔助函數轉換為 class。 在內部使用 shared_ptr 而不是原始指針。 ETC...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM