james
james

Reputation: 1155

initialise derived classes from base class

I have got a base class similar to this (but the following does not compile):

struct Base {
    virtual void foo()=0;

    virtual void init() 
    {
        using Derived = typename std::remove_reference<decltype(*this)>::type;
        *this = Derived(); // does not compile as Base is an abstract class
    }
};

Base has lots of derived classes and what I want to do is to let all of its derived classes to have this init() function inherited from Base and initialise themselves (by calling their constructors). And also allow them to override init() if they want.

Questions:

  1. I know it doesn't compile. What if my Base was not abstract class, does it work? I wonder if the this pointer will be interpreted as derived object pointer?

  2. How to achieve what I want?

-------------------------------EDIT--------------------------------------

To clarify a bit, The init() function is actually doing reset. It reset each derived object to their default state. I want this to be in the Base class with such a default behaviour, and if the derived class want some different reset(), they are free to override it.

Upvotes: 1

Views: 280

Answers (2)

Jeff Garrett
Jeff Garrett

Reputation: 7383

You want to call a different function based on the type of the derived class. This is polymorphism in C++. You have at your disposal the usual suspects:

  1. Have a virtual function which derived classes override. i.e. dispatch based on dynamic type.
  2. Find the static type in some way and use overloading. i.e. dispatch based on static type.

CRTP is one way to accomplish the second, having the derived say its true type at the point of inheritance.

An extremely hacky way to accomplish the second, which to be clear I'm not recommending, but may be required in a dysfunctional organization in which you have no other options: attempt to dynamic_cast to the various options for the derived class. This is likely to be fragile. But even having a reset function at all, instead of using construction and destruction is fragile.

I recommend re-evaluating your need for a reset member function, ask on SO about what you are trying to accomplish with it, and try not to lower the quality of your work product as an end-run around interacting with your organization. (My opinion.)

Upvotes: 0

oLen
oLen

Reputation: 5547

A few users mentioned CRTP (Curiously Recurring Template Pattern) in the comments, without showing a concrete solution, so here is one:

template <typename CRTP>
struct Base {
  virtual void foo()=0;

  virtual void init() 
  {
    static_cast<CRTP&>(*this) = CRTP{};
  }
};

struct Derived : public Base<Derived> {
  void foo() override {}
};

Upvotes: 1

Related Questions