Reputation: 1701
I have a base class and many derived classes.
The constructor of derived classes all need to call a function reset()
with the same signature. As a result, I want to declare a pure virtual function virtual void reset() = 0
in base class as an Interface.
However, the problem is :
It is not supposed to call a virtual function in Constructor.
But I want reset()
to be an interface provided by the base class. So that all derived classes have to implement reset respectively.
What should I do?
Upvotes: 0
Views: 131
Reputation: 217293
You might create factory:
struct Base
{
virtual ~Base() = default;
virtual void reset() = 0;
template <typename Der, typename ... Ts>
static std::unique_ptr<Der> Make(Ts&&... args)
{
static_assert(std::is_base_of<Base, Der>::value, "!");
auto p = std::make_unique<Der>(std::forward<Ts>(args)...);
p->reset();
return p;
}
};
struct Derived
{
void reset() override { /*..*/ }
};
Upvotes: 1
Reputation: 6476
Instead of forcing them to call a function (which you anyway cannot guarantee), make the base class constructor expect a parameter that includes the behavior you need to have.
That way, the base class is self-contained and has all the required information by the time its constructor runs.
For example, if you were thinking of something like this:
class Base
{
public:
Base()
{
reset();
}
protected:
virtual void reset() = 0;
void setValue(int value);
};
class Derived : public Base
{
public:
void reset() override
{
setValue(20);
}
};
you can do this instead:
class Base
{
public:
explicit Base(int value)
{
setValue(value);
}
private: // can be private
void setValue(int value);
};
class Derived : public Base
{
public:
Derived()
: Base(20)
{
}
};
Upvotes: 5