我需要解析XML並在C++中創建對應於XML元素的對象,並將XML元素的屬性作爲屬性打包到這些對象中。 XML元素/屬性和相應的C++類/屬性繼承自具有派生對象通用屬性的基礎對象。多態性或屬性字典?
我正在考慮使用基類的公共屬性和派生類只需要定義對象的特定屬性。然而,有人告訴我,使用標準多態不是一個好主意,因爲解決方案不夠通用 - 在XML中添加/更改屬性需要向C++類添加/更改相應的屬性,這需要更改太多的代碼。一個更好更抽象的解決方案是將一個屬性字典放在基類中,並通過搜索字典來訪問各個屬性。我想問社區這個建議是否對生產代碼更好。
下面是一個例子,其中車輛是基礎對象,並且不同的車輛類型從它繼承。 車輛物體具有所有車輛通用的name
和weight
屬性。下面是一個示例XML片段:
<car name="Toyota" weight="3500" passengers="4" />
<boat name="Yamaha" weight="3700" draft="16" />
基類:
class vehicle {
public:
string name;
string weight;
};
派生類:
class car : public vehicle {
public:
string passengers;
};
class boat : public vehicle {
public:
string draft;
};
現在,當我的解析器發現汽車和船的元素我實例:
boat *b = new boat();
car *c = new car();
對於船我可以簡單地訪問所有成員b->name
,b->weight
和b->draft
。在C++對象從XML實例化後,我們在每個屬性上完成了大量針對對象的工作,因此我們的目標不是簡單地將XML加載到程序中。
另一種方法:
#define TAG_XML_ATTRIBUTE_NAME "name"
#define TAG_XML_ATTRIBUTE_WEIGHT "weight"
#define TAG_XML_ATTRIBUTE_PASSENGERS "passengers"
#define TAG_XML_ATTRIBUTE_DRAFT "draft"
. . .
class vehicle {
public:
map<string, string> arguments;
// Get argument by name searching the arguments dictionary.
string GetArgumentOrEmpty(const string& argumentName);
};
class car : public vehicle {
public: // All propeties are in the base class dictionary.
};
class boat : public vehicle {
public: // All propeties are in the base class dictionary.
};
所有派生類具有arguments
圖;爲了得到屬性值,我們掃描詞典以按名稱查找屬性,然後讀取它的值,例如, GetArgumentOrEmpty(TAG_XML_ATTRIBUTE_WEIGHT)
。現在的CPU速度很快,因此搜索字典不會明顯影響性能。元素/屬性的命名空間從結構化(作爲類成員)到平坦(作爲#define列表),但它們將全部位於同一位置。代碼更抽象;儘管對象處理代碼由於額外的間接尋址而變得更加複雜,但如果屬性名稱更改,則不需要更改;例如如果在XML改變people
passengers
,#定義會顯得有點尷尬,但使用它不會有更改代碼:
#define TAG_XML_ATTRIBUTE_PASSENGERS "people"
是否基於字典的屬性訪問方法存在足夠的好處將其用於生產代碼而不是使用常規的類屬性?如果是這樣,是僅僅爲了這個特定的XML解析情況還是用字典搜索替換多態性並用字符串名稱替換類屬性通常是一個更好的主意?
Christophe,你能否請你完成你的想法「事實上,一些遊戲編碼專家,比如......」 - 這裏的細節非常有價值。 – sun2sirius
@ sun2sirius對不起,在寫作過程中,這句話被切斷了,並失去了。我編輯完成了這個句子。 – Christophe