2015-02-07 57 views
0

我將我在java/as3中創建的網絡api移植到C++。我對C++很陌生,所以我不熟悉所有可用的工具。調用一個未知的構造函數(替代反射)C++

我有一個叫Packet的類。在我的java/as3類中,數據包有2個hashmaps,一個用於classToId,另一個用於idToClass。

然後我註冊一個帶有id和它的類對象的派生包。

當收到一個包時,我得到它的包ID,然後用這個ID創建一個新的包。

在AS3代碼然後我用:

public static function getNewPacket(id:int):Packet 
    { 
     try 
     { 
      var clazz:Class = getClassById[id]; 
      return (clazz == null ? null : Packet(new clazz())); 
     } 
     catch (e:Error) 
     { 
      trace("Skipping packet with id " + id + ": " + e.message); 
     } 
     return null; 
    } 

正如你所看到的,使用反射調用構造函數。然而,在c + +中,我不知道如何創建這個。 我不能使用靜態數據包列表,因爲這是一個API類(所以這個類會在使用這個API的應用程序中擴展)

+0

底線 - C++中沒有'reflection'。你需要考慮「在Java框外」來提出一個解決方案。 – PaulMcKenzie 2015-02-07 23:58:27

+0

這就是爲什麼我問這個問題,我不知道可用來替代反射的工具。 – Duckdoom5 2015-02-08 00:00:48

+0

可以存儲在'getClassById'映射中的'Class's有什麼約束?他們可以是任何具有無參數構造函數的類,還是需要成爲某個基類的子類 - 它是在您的應用中定義的基類還是其他類?還是有一個可接受的類的簡短列表? – ajb 2015-02-08 00:01:38

回答

2

典型的解決方案是有一個工廠函數,它將ID到實際的班級。假設我們有一組類來處理形狀:

class Shape { ... }; 
class Square : public Shape { ... } ; 
class Triangle : public Shape { ... }; 

enum ShapeID { SquareID, TriangleID, ... } 

Shape *shapeFactory(ShapeID id) 
{ 
    switch(id) 
    { 
     case SquareID: return new Square; 
     case TriangleID: return new Triangle; 
     ... 
    }; 
    return NULL; 
} 

的選擇,如果你真的不知道自己想要什麼課「直到後來」是提供創建正確ID的功能。

所以,如果你想成爲能夠與用戶自定義形狀,以延長你的形狀的系統,你可以做這樣的事情:

typedef Shape* (*shapeCreatorFunc)(); 
... 

Shape* createStar() 
{ 
    return new Star; 
} 

... 
typedef std::map<ID, ShapeCreatorFunc> ShapeMap; 
ShapeMap map; 
... 
map[SquareID] = createSquare; 
map[TriangleID] = createTriangle; 
map[StarID] = createStar; 
.... 
ShapeMap::iterator it = map.find(id); 
if (it != map.end()) 
{ 
    Shape *s = it.second(); 
} 

這仍然依賴於Shape是一個共同的基類。如果不是這樣,我不確定用易於理解/解釋的方式解決這個問題是多麼容易。

+0

感謝隊友,正是我在找的東西。底部解決方案爲我解決了:) – Duckdoom5 2015-02-08 00:05:16

相關問題