Ищу: доступ к члену производного класса из указателя на базу.
Reductio ad absurdum:
class Base
{
public:
int member_of_base;
};
class Derived : public Base
{
public:
int member_of_derived;
};
Я сейчас использую шаблоны:
template <class T>
class Client
{
T* data; // T is Base or Derived
};
Существует несколько уровней композиции в иерархии классов, поэтому мне нужно провести параметр типа шаблона через всю иерархию. Каков наилучший подход для преодоления этого?
Очевидно, я не могу получить доступ к члену Derived через указатель на Base, т. Е.
Base* foo = new Derived();
foo->member_of_derived; // no go
Таким образом, я использую:
Client<Base>
Client<Derived>
Я пытаюсь найти решение, которое работает без шаблонов. Опции, которые я знаю, будут работать:
- void * // простой старый C и приведение по необходимости, все они указатели
(как в адресах памяти) в машине
static_cast<Derived*>(pointer_to_base);
// введите safe во время компиляции.
- завершение приведения в шаблонном методе Клиента (не путать с шаблоном дизайна здесь)
Последний вариант кажется наиболее «элегантным», то есть:
template <class T>
T* get_data() const { return static_cast<T*>(data); }
Однако, глядя здесь и там, можно сказать, что может существовать неизвестный мне путь.
Я видел CRTP, но это возвращает меня к шаблонам, что является оригинальной вещью, без которой я хочу обойтись.
Каковы пути или популярные подходы для достижения такой цели?
Реальный код использует shared_ptr, weak_ptr и enable_shared_from_this со слабым_from_this. Я ищу безопасный тип доступа "полиморфный член".
РЕДАКТИРОВАТЬ: они не просто "целые". Они могут быть совершенно разных типов, как в protobuf в base и Json :: Value в производном. И я пытаюсь использовать указатели на Base / Derived, что, в свою очередь, даст мне доступ к их соответствующим членам.