Question

I have got a deserialization scenario for an object hierarchy, in which most objects contain pointers to other objects, but don't own them.

I am trying to implement a two-step process in which:

  1. Objects are created, Register(Object* pObject)ed to an ID, data is read. Pointer members are serialized as unique IDs, so upon reading them back, I RegisterResolver(int id, Object** ppMember)s.
  2. Resolvers are processed: IDs are looked up and the correct address is written to the address that is *ppMember (notice the dereferencing).

The problem:

  • I want to enforce that only pointers to objects of or derived from a certain Base class be registered, however Derived** can't be converted to Base**.
  • I want to at least avoid ambiguity when using void* (not void**) that Derived** / Base** can be both converted to, but then so can Derived* / Base*.

In the following scenario:

struct A: public Serialized
{
  int blah;
};

struct B: public Serialized
{
  float fBlah;
  A*    pTarget;
};

B myB;

If the interface is RegisterResolver(int id, void* ppObject), there's no guarantee that client code won't pass myB.pTarget instead of &myB.pTarget.

What can I do to improve the [type-]safety and readability of this solution?

(The target platforms are x86 and ARM.)

Was it helpful?

Solution 2

As the original issue was also concerning readability and I wanted to minimize potentially confusing parameters on the interface, I've iterated on Ben Voigt's answer and ended up with this:

template<typename T>
void RegisterResolver(int id, T** ppObject)
{
  // assert(ppObject != 0);
  Base* pBase(*ppObject); // not used

  // implementation
}

OTHER TIPS

A template should help. How about

template<typename T>
void RegisterResolver(int id, T** ppObject, Base* extra = (T*)0);

This permits an argument of any type Derived** for which there is an implicit conversion from Derived* to Base*.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top