mercredi 12 septembre 2018

Member of derived by pointer to base, static_cast, crtp, removing templates

Looking for: accessing member of a derived class from a pointer to base.

Reductio ad absurdum:

class Base
{
public:
    int member_of_base;
};

class Derived : public Base
{
public:
    int member_of_derived;
};

I'm currently using templates:

template <class T>
class Client
{
    T* data; // T is Base or Derived
};

There are few levels of composition in the class hierarchy, so I have to carry the template type parameter through all of the hierarchy. What is the best approach to overcome this? Obviously I cannot access the member of Derived via a pointer to Base, i.e:

Base* foo = new Derived();
foo->member_of_derived; // no go

Thus, I'm using:

Client<Base>
Client<Derived>

I'm trying to come up with a solution that works without the templates. Options that I know would work:

  • void* //plain old C and casting as necessary, they're all pointers (as in memory addresses) in the machine
  • static_cast<Derived*>(pointer_to_base); //type safe at compile time.
  • wrapping the cast in a Client's template method (not to be confused with a design pattern here)

The last option seems to be the most "elegant", i.e:

template <class T>
T* get_data() const { return static_cast<T*>(data); }

However, looking here and there tells me there might exist a way unknown to me. I saw CRTP, but that brings me back to templates, which is the original thing I want to go without. What are the ways, or popular approaches, to achieve such a goal?

The real code uses shared_ptr, weak_ptr and enable_shared_from_this with weak_from_this. I'm looking for a type safe "polymorphic member" access.

EDIT: they're not just "ints". They can be totally different types, as in protobuf in base and Json::Value in derived. And I'm trying to use the pointers to Base/Derived, which in turn would give me access to their respective members.

Aucun commentaire:

Enregistrer un commentaire