Reputation: 1155
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:
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?
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
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:
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
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