我希望有一個從類到每個類的實例的映射。目標是爲一個基於組件的遊戲引擎提供一個組件容器,其中一個對象最多隻能有一種組件類型。如何在C++中將類類映射到該類的實例?
在Java中,我只能使用類對象作爲關鍵。我如何在C++中做類似的事情?我最初的研究表明使用typeid(component_instance).name()作爲關鍵。有一個更好的方法嗎?
我希望有一個從類到每個類的實例的映射。目標是爲一個基於組件的遊戲引擎提供一個組件容器,其中一個對象最多隻能有一種組件類型。如何在C++中將類類映射到該類的實例?
在Java中,我只能使用類對象作爲關鍵。我如何在C++中做類似的事情?我最初的研究表明使用typeid(component_instance).name()作爲關鍵。有一個更好的方法嗎?
與Python或Java等動態語言不同,C++中的類本身不是對象。在運行時,它們只是不存在(就像程序員的觀點)。
你的typeid
方法並沒有那麼糟糕,但是對於性能問題,我會使用散列或數字ID(就像在你的類中定義爲靜態的整數)而不是字符串。
我喜歡靜態整數ID的想法;我想這是由我來確保每個ID是唯一的? – Jake 2011-12-19 14:56:54
如果不需要持久化,那麼生成「唯一」標識符相當容易。爲每個id使用一個靜態實例,用'= getNextId();'作爲初始值,'int getNextId(){static int id = 0; return ++ id; }'。 – 2011-12-19 15:01:53
@Jake:我想到了從類名生成的靜態(編譯時)字符串散列。 (例如:http://molecularmusings.wordpress.com/2011/06/24/hashed-strings/) – Constantinius 2011-12-19 15:04:50
C++類不是reified所以你沒有類對象。
你可能會考慮擁有自己的類描述符(作爲一個約定)。你甚至可以爲你自己做預處理器。
也許你可以從Qt meta-object system中學習並從中獲得靈感,該程序使用名爲moc的預處理器。也許,使用Qt對象比創建你自己的元類系統要簡單得多。
您可以創建類型,如這種獨特的鍵(注意,這僅是單線程執行):
struct TypeManager
{
private:
static int next_id(void)
{
static int id = 0;
return ++id;
}
public:
template<typename T>
static int get_type_id(void)
{
static int const id = next_id();
return id;
}
};
用法:
int unique_bool_id = TypeManager::get_type_id<bool>();
int unique_float_id = TypeManager::get_type_id<float>();
或使用['typeid' /'type_info'](http://www.cplusplus.com/reference/std/typeinfo/type_info /)而不依賴於未定義的行爲(你甚至假設函數指針和整數具有相同的大小)。 – 2011-12-19 15:16:38
@phresnel我明白了,謝謝!想出了與衆不同的東西。 – Baltram 2011-12-19 15:23:02
@phresnel:這是我的想法。這看起來像'typeid'的重新實現。爲什麼不直接使用'typeid'?如果需要,您可以使用名稱字段作爲密鑰。 – Omnifarious 2011-12-19 15:24:46
在JAVA中,一個Singleton類確保一類只有一個實例。另外在C++中,如果您只想創建一個類的一個實例,則使用Singleton模式。 使用Singleton設計模式,在應用程序的整個生命週期中只需要一個對象實例。
Singleton類在第一次訪問時被實例化,並且之後使用相同的實例直到應用程序退出。
Singleton設計模式通常用於控制對資源(如數據庫連接或套接字)的訪問。假設我們的數據庫只有一個連接的許可證。一個Singleton連接對象可以確保在任何時候只能建立一個連接。
#include <iostream>
using namespace std;
class Singleton
{
private:
static bool instanceFlag;
static Singleton *single;
Singleton()
{
//private constructor
}
public:
static Singleton* getInstance();
void method();
~Singleton()
{
instanceFlag = false;
}
};
bool Singleton::instanceFlag = false;
Singleton* Singleton::single = NULL;
Singleton* Singleton::getInstance()
{
if(! instanceFlag) // use the instanceFlag in all methods and functions to check if object already exists
{
single = new Singleton();
instanceFlag = true;
cout<<"NO OBJECT WAS PREVIOUSLY CREATED"<< endl;
cout<<"__________________________________________________"<< endl;
return single;
}
else
{
cout<<"OBJECT ALREADY EXISTS!!"<< endl;
cout<<"__________________________________________________"<< endl;
return single;
}
}
void Singleton::method()
{
cout << "Method of the singleton class" << endl;
}
int main()
{
Singleton *sc1,*sc2;
cout<<"Object 1"<< endl;
sc1 = Singleton::getInstance();
cout<<"Object 2"<< endl;
sc2 = Singleton::getInstance();
return 0;
}
我不想確保每個類只有一個實例,我想要一個包含從基類繼承的對象的集合,並且它只包含到目前爲止添加的每個子類的一個實例。 – Jake 2011-12-19 18:40:05
我建議你使用錯誤的方法。 – Omnifarious 2011-12-19 15:06:51
聽起來像是「描述問題的經典案例,而不是你想象的解決方案」。 – 2011-12-19 15:17:15
而不是使用name()(不保證它是唯一的),你可以將type_info包裝成指向它們的指針,並使用less()方法來比較它們。或者,如果你使用C++ 11,你可以使用'type_index',這是我剛剛描述的標準版本。 – 2011-12-19 16:04:09