Разработка моей программы, чтобы избежать приведения от базового к производному классу - PullRequest
0 голосов
/ 09 ноября 2010

Хорошо, мне кажется, что требуется прямое приведение от базового к производному, и я думаю, что это может быть проблемой проектирования, поэтому я объясню, что я делаю, и вы можете сказать мне, что мне нужно изменить. XML-файл определяет группу объектов, которые похожи. Они имеют один и тот же базовый класс. Основная функция определена в базовом классе DoWork () и является виртуальной.

Моя программа загружает файл XML, создает производные классы и присваивает их вектору базового класса типа.

Все отлично, программа работает. Я могу перебрать вектор и вызвать DoWork ();

Теперь я добавил слой с графическим интерфейсом, чтобы вы могли изменять объекты и записывать обратно XML-файл. Итак, теперь мой GUI-код имеет доступ к вектору указателей базового класса. Но это не очень хорошо, потому что мне нужна информация из производного класса, чтобы я мог выписать файл XML. Является ли единственным решением для этого динамического литья? Мог ли я как-то изменить дизайн? Я знаю, что приведение от основания к выводу неодобрительно.

РЕДАКТИРОВАТЬ: мой графический интерфейс должен отображать информацию, которая также имеет производный класс. Недостаточно просто иметь класс сериализации.

Ответы [ 6 ]

4 голосов
/ 09 ноября 2010

Не могли бы вы добавить, например, виртуальный serialize метод для каждого класса, чтобы ваш цикл вывода мог просто перебирать вектор и вызывать (*it)->serialize() для базового указателя для каждого элемента?

3 голосов
/ 09 ноября 2010

Здесь есть два разных подхода. Первый предоставляет виртуальный метод, который генерирует XML, соответствующий элементу.

Второй подход заключается в предоставлении интерфейса посетителя: в основном вы определяете виртуальный метод, который принимает тип visitor. Тип посетителя будет вызываться с текущим объектом на каждом уровне иерархии, генерируя тип механизма двойной отправки. Таким образом, виртуальная отправка преобразуется в самый производный объект, который будет вызывать объект посетителя для сериализации.

Первый подход проще, в то время как второй имеет преимущество более слабой связи между каждым объектом в иерархии и фактическим форматом сериализации. То есть вы можете создавать разных посетителей, которые могут сериализоваться в разные форматы, без необходимости изменять код в вашей текущей иерархии.

1 голос
/ 09 ноября 2010
  1. Опубликовать небольшой пример кода -

  2. Звучит так, как будто базовому классу нужен виртуальный WriteXML () - просто догадаться на этом этапе

1 голос
/ 09 ноября 2010

Вы можете определить метод в вашем базовом классе, который печатает объект в XML, а затем сделать так, чтобы все ваши производные классы обеспечивали его собственную реализацию. По сути, вы делегировали бы печать производным классам.

РЕДАКТИРОВАТЬ: или, в более общем случае, следуйте предложению Оли и напишите метод serialize() для базового класса, который возвращает легко усваиваемую коллекцию важных элементов данных этого объекта (например, список пар ключ-значение). Ваша основная программа может затем перебрать сериализованную форму каждого объекта и решить, что с ней делать.

0 голосов
/ 09 ноября 2010

Если вы определяете такое же поведение в базовом классе, которое необходимо использовать для получения данных в производном классе, тогда вы можете обрабатывать все объекты одинаково. Для производных классов, у которых ранее не было такого поведения, вы можете заставить их работать молча. Посмотрите на намерение составного шаблона проектирования.

0 голосов
/ 09 ноября 2010

Либо реализуйте функцию в базовом классе, которую производные классы могут переопределить, чтобы предоставить необходимую информацию для записи Xml, либо оставьте сам объект в Xml.Оба эти решения не требуют, чтобы вы знали, что это такое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...