我需要解析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