我有一个基类和许多派生类。
派生类的构造函数都需要调用具有相同签名的函数reset()
。结果,我想在基类中将纯虚函数virtual void reset() = 0
声明为Interface。
但是,问题是:
不应在Constructor中调用虚函数。
但是我希望reset()
是基类提供的接口。这样所有派生类都必须分别实现reset。
我该怎么办?
答案 0 :(得分:5)
使基类构造函数期望一个包含所需行为的参数,而不是强制它们调用函数(无论如何您都不能保证)。
这样,基类是独立的,并在构造函数运行时具有所有必需的信息。
例如,如果您正在考虑这样的事情:
class Base
{
public:
Base()
{
reset();
}
protected:
virtual void reset() = 0;
void setValue(int value);
};
class Derived : public Base
{
public:
void reset() override
{
setValue(20);
}
};
您可以改为:
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)
{
}
};
答案 1 :(得分:1)
您可以创建工厂:
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 { /*..*/ }
};