функция, вызываемая конструкторами производных классов, не должна быть чисто виртуальной в базовом классе - PullRequest
0 голосов
/ 25 июня 2019

У меня есть базовый класс и много производных классов.

Конструктор всех производных классов должен вызывать функцию reset() с той же сигнатурой.В результате я хочу объявить чисто виртуальную функцию virtual void reset() = 0 в базовом классе как интерфейс.

Однако проблема заключается в следующем:

Не предполагается вызывать виртуальную функцию в конструкторе.

Но я хочу, чтобы reset() был интерфейсом, предоставленным базойучебный класс.Так что все производные классы должны реализовывать сброс соответственно.

Что мне делать?

Ответы [ 2 ]

5 голосов
/ 25 июня 2019

Вместо того, чтобы заставлять их вызывать функцию (которую вы в любом случае не можете гарантировать), заставьте конструктор базового класса ожидать параметр, который включает в себя поведение, которое вам необходимо.

Таким образом, базовый класс является автономным и имеет всю необходимую информацию к моменту запуска его конструктора.


Например, если вы думаете о чем-то вроде этого:

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 голос
/ 25 июня 2019

Вы можете создать фабрику:

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 { /*..*/ }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...