2011-12-19 60 views
1

我希望有一個從類到每個類的實例的映射。目標是爲一個基於組件的遊戲引擎提供一個組件容器,其中一個對象最多隻能有一種組件類型。如何在C++中將類類映射到該類的實例?

在Java中,我只能使用類對象作爲關鍵。我如何在C++中做類似的事情?我最初的研究表明使用typeid(component_instance).name()作爲關鍵。有一個更好的方法嗎?

+1

我建議你使用錯誤的方法。 – Omnifarious 2011-12-19 15:06:51

+0

聽起來像是「描述問題的經典案例,而不是你想象的解決方案」。 – 2011-12-19 15:17:15

+0

而不是使用name()(不保證它是唯一的),你可以將type_info包裝成指向它們的指針,並使用less()方法來比較它們。或者,如果你使用C++ 11,你可以使用'type_index',這是我剛剛描述的標準版本。 – 2011-12-19 16:04:09

回答

2

與Python或Java等動態語言不同,C++中的類本身不是對象。在運行時,它們只是不存在(就像程序員的觀點)。

你的typeid方法並沒有那麼糟糕,但是對於性能問題,我會使用散列或數字ID(就像在你的類中定義爲靜態的整數)而不是字符串。

+0

我喜歡靜態整數ID的想法;我想這是由我來確保每個ID是唯一的? – Jake 2011-12-19 14:56:54

+0

如果不需要持久化,那麼生成「唯一」標識符相當容易。爲每個id使用一個靜態實例,用'= getNextId();'作爲初始值,'int getNextId(){static int id = 0; return ++ id; }'。 – 2011-12-19 15:01:53

+0

@Jake:我想到了從類名生成的靜態(編譯時)字符串散列。 (例如:http://molecularmusings.wordpress.com/2011/06/24/hashed-strings/) – Constantinius 2011-12-19 15:04:50

1

C++類不是reified所以你沒有類對象。

你可能會考慮擁有自己的類描述符(作爲一個約定)。你甚至可以爲你自己做預處理器。

也許你可以從Qt meta-object system中學習並從中獲得靈感,該程序使用名爲moc的預處理器。也許,使用Qt對象比創建你自己的元類系統要簡單得多。

0

您可以創建類型,如這種獨特的鍵(注意,這僅是單線程執行):

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>(); 
+0

或使用['typeid' /'type_info'](http://www.cplusplus.com/reference/std/typeinfo/type_info /)而不依賴於未定義的行爲(你甚至假設函數指針和整數具有相同的大小)。 – 2011-12-19 15:16:38

+0

@phresnel我明白了,謝謝!想出了與衆不同的東西。 – Baltram 2011-12-19 15:23:02

+0

@phresnel:這是我的想法。這看起來像'typeid'的重新實現。爲什麼不直接使用'typeid'?如果需要,您可以使用名稱字段作爲密鑰。 – Omnifarious 2011-12-19 15:24:46

0

在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; 
} 
+0

我不想確保每個類只有一個實例,我想要一個包含從基類繼承的對象的集合,並且它只包含到目前爲止添加的每個子類的一個實例。 – Jake 2011-12-19 18:40:05