Сбой dynamic_cast для производного типа. Почему? - PullRequest
1 голос
/ 02 апреля 2011

Я хотел бы получить помощь по проблеме, с которой я столкнулся.

Я использую сериализацию (точнее TinyXml) для сохранения объектов в файле, и у меня возникла проблема с десериализацией.

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

Каждый сохраняемый мной объект наследует ASerializable, напрямую или нет.

Вот моя иерархия:

//Holds pure virtual method: TiXmlElement * ToXml() = 0;
class ISerializable;

// Basic implementation of ISerializable, this class has a unique ID.
class ASerializable : public ISerializable;

// For security sake, this class is not real, just a demonstration of my problem.
// Overrides TiXmlElement * ToXml()
class Base : public ASerializable;

// Overrides TiXmlElement * ToXml()
class Derived : public Base;

После десериализации я добавляю каждый созданный мной объект в статическую карту (ID, ASerializable *), которая хранит данные до разыменования.

Как разыменовывать объекты

Я использую шаблонный класс, который содержит T **, который является указателем на разыменование после того, как вся десериализация сделана.

template<typename T>
class Reference<T> {
    T** ref_ptr;
    int id; // This is the ID of the referenced object
    void Dereference();
}

По сути, Reference<T>::Dereference() получает объект на карте, затем приводит его к хорошему типу (то есть T*) и изменяет значение *ref_ptr на приведенный объект.

Я использую dynamic_cast<T*>( objects_map[id] ) для приведения моего объекта, и по какой-то причине он каждый раз терпит неудачу.

Я не могу привести от ASerialisable* к Derived* без потери данных Derived.

Вот схема, которую я хочу достичь:

  1. При десериализации элемент добавляет себя на карту объектов;

  2. Если объект является ссылкой, добавьте ссылку (с хорошим типом, я знаю ее) в стек

  3. После завершения десериализации снимите все ссылки и вызовы Dereference()

  4. Будь по-настоящему счастлив.

Спасибо, оооооооооооооооочее потратили время и драгоценную помощь.

{} наслаждаться РЕДАКТИРОВАТЬ : Хорошо, я постараюсь быть более понятным, но это немного сложно.

Когда я анализирую свой XML-файл, иногда появляются элементы с именем <reference id="X">: это ссылки на другой экземпляр (ASerializable);

Когда я сталкиваюсь с объектом <reference>, я добавляю его в стек, чтобы позднее разыменовывать его. Когда я сталкиваюсь с конкретным объектом, например <Base id="X" ... data ... />, я его строю, а затем добавляю в карту объектов как ASerializable*;

После того, как я закончил создание всех своих объектов, я снимаю стеки с каждой ссылки и вызываю Dereference(), чтобы ДОЛЖНО пойти получить РЕАЛЬНЫЙ МОМЕНТ объекта, привести его к хорошему типу, используя dynamic_cast, затем изменить значение его ref_ptr для указания этого объекта.

Не стесняйтесь задавать другие вопросы, если это необходимо.

Ответы [ 2 ]

2 голосов
/ 02 апреля 2011

Есть ли в вашем базовом классе хотя бы один виртуальный метод? Если его нет, сделайте деструктор виртуальным.


Возможно, вы захотите использовать Boost.Serialization , он прекрасно справляется с сериализацией в и из файлов XML.

1 голос
/ 02 апреля 2011

Хорошо, спасибо всем за ваше время. Я нашел проблему.

В моей иерархии все было нормально, проблема заключалась в копировании вектора. Затем содержащиеся в нем указатели менялись, поэтому мой ref_ptr of Reference был поврежден.

{} наслаждаться

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