Обеспечение указателя на тип указателя во время компиляции

У меня есть сценарий десериализации для иерархии объектов, в котором большинство объектов содержат указатели на другие объекты, но не владеют ими.

Я пытаюсь реализовать двухэтапный процесс, в котором:

  1. Объекты созданы, Register(Object* pObject)Идентифицируется в ID, данные читаются. Члены-указатели сериализуются как уникальные идентификаторы, поэтому, прочитав их, я RegisterResolver(int id, Object** ppMember)s.
  2. Обработчики обрабатываются: идентификаторы ищутся и правильный адрес записывается на адрес, который *ppMember (обратите внимание на разыменование).

Эта проблема:

  • Я хочу, чтобы только указатели на объекты или получены из определенного Base класс должен быть зарегистрирован, однако Derived** не может быть преобразован в Base**,
  • я бы хотел по крайней мере избегать двусмысленности при использовании void* (не void**) тот Derived** / Base** может быть преобразован в, но тогда так может Derived* / Base*,

В следующем сценарии:

struct A: public Serialized
{
int blah;
};

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

B myB;

Если интерфейс RegisterResolver(int id, void* ppObject)нет гарантии, что код клиента не пройдет myB.pTarget вместо &myB.pTarget,

Что я могу сделать, чтобы улучшить [type-] безопасность и удобочитаемость этого решения?

(Целевые платформы — x86 и ARM.)

0

Решение

Шаблон должен помочь. Как насчет

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

Это позволяет аргумент любого типа Derived** для которого есть неявное преобразование из Derived* в Base*,

1

Другие решения

Поскольку исходная проблема также касалась читабельности, и я хотел минимизировать потенциально запутанные параметры интерфейса, я повторил Бен Фойгтответ и закончился этим:

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

// implementation
}
0

По вопросам рекламы [email protected]