Micael Bergeron
Micael Bergeron

Reputation: 1184

dynamic_cast to derived type fails, Why?

I'd like to have some help on an issue I face.

I'm using serialization (TinyXml to be precise) to save objects in a file and I have a problem on deserialization.

My objects contain pointers, which are not saved directly but instead the ID of the object pointed to is saved.

Every object I save derivate ASerializable, directly or not.

Here is my hierarchy :

//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;

Upon deserialization, I add each object I create into a static map(ID, ASerializable*), which holds the data until dereference.

How I dereference objects

I use a template class which holds a T**, which is the pointer to dereference once all the deserialization is done.

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

Basically, Reference<T>::Dereference() gets the object in the map, then cast it to the good type (which is T*) and change the value of *ref_ptr to the cast object.

I'm using dynamic_cast<T*>( objects_map[id] ) to cast my object and for some reason, it fails everytime.

I can't cast from a ASerialisable* to a Derived* without losing the data of Derived.

Here is the pattern I want to achieve :

  1. On deserialized, the item add itself to the objects map;

  2. If the object is a reference, add a Reference (with the good type, I know it) to a Stack

  3. Once all deserialization is done, unstack all references and calls Dereference()

  4. Be really happy.

Thank you soooo dor your time and precious help, really appreciated.

{enjoy} EDIT : Okay, I'll try to be clearer, but it is a bit complex.

When I parse my XML file back, there are sometimes element called <reference id="X"> : those are reference to another instance (ASerializable);

When I encounter a <reference> object, I add it to a stack, to be dereferenced later. When I encounter a specific object, like a <Base id="X" ... data ... /> I build it, then I add it to a object map, as an ASerializable*;

Once I finished building all my objects, I unstack each of the reference and call Dereference(), that SHOULD go get the REAL INSTANCE of the object, cast it to the good type using dynamic_cast then change the value of his ref_ptr to point that object.

Don't hesitate to ask for other questions if needed.

Upvotes: 1

Views: 390

Answers (2)

Micael Bergeron
Micael Bergeron

Reputation: 1184

Alright, thank you all for your time. I found the problem.

Everything was fine in my hierarchy, the problem was a vector that was being copied. The pointers it contained were then changing so my the ref_ptr of Reference was corrupted.

{enjoy}

Upvotes: 1

Sam Miller
Sam Miller

Reputation: 24174

Does your base class have at least one virtual method? If it has none, make the destructor virtual.


You might want to look into using Boost.Serialization, it handles serializing to and from XML files nicely.

Upvotes: 2

Related Questions