[英]How to register an object using string or int as key dynamically, and store, access it with the key in 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
class 以提供接口。
如何使用給定的數據類型和鍵動態注冊 object? 是否有任何設計模式可以滿足此要求?
我在我的團隊中構建了您所描述的東西,作為用於跨應用程序路由消息的庫的內部。
如果您卡在 C++11 上(這樣std::any
或std::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.