Search code examples
c++pointersreadabilitytype-safety

Enforcing pointer to pointer type at compile time


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.)


Solution

  • 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
    }