Мне нужно разобрать 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;
};
Теперь, когда мой анализатор находит машину и лодочные элементы I инстанцирует:
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)
. В наши дни процессоры быстрые, поэтому поиск словаря не будет заметным, влияя на производительность. Пространство имен элементов/атрибутов происходит от структурированных (как членов класса) до flat (в виде #define list), но все они будут находиться в одном месте. Код более абстрактный; хотя код обработки объекта становится более сложным из-за дополнительной косвенности, ему не нужно изменять, если имя атрибута изменяется; например если passengers
в изменениях XML в people
, то #define будет выглядеть немного неудобно, но код, который использует его не придется менять:
#define TAG_XML_ATTRIBUTE_PASSENGERS "people"
ли на основе словаря метод доступа свойство настоящего достаточно пользы использовать его для производственного кода вместо использования обычных свойств класса? Если да, то только для этого конкретного случая XML-разбора или для замены полиморфизма поиском словаря и замены свойств класса с помощью имен строк является лучшей идеей в целом?
Christophe, не могли бы вы закончить свою мысль? «На самом деле некоторые эксперты по кодированию игр, такие как ...» - подробности здесь чрезвычайно ценны. – sun2sirius
@ sun2sirius Извините, предложение было сокращено и потеряно во время написания. Я редактировал для завершения предложения. – Christophe