Почему эта функция не отменяет функцию базового класса - PullRequest
2 голосов
/ 05 мая 2020

Итак, вот базовый класс:

class MovieRepo {
protected:
    MyLista<Movie> all;
public:
    MovieRepo();
    void store(const Movie& m);
}

И это переопределение:

class RepoFile : public MovieRepo
{
private:
    string filename;
    void loadFromFile();
    void storeToFile();

public:

    RepoFile(string _filename) : filename{ _filename } { this->loadFromFile(); };

    void store(const Movie& m) override { // here is the error
        MovieRepo::store(m);
        storeToFile();
    }
}

Он говорит: 'RepoFile :: store': метод со спецификатором переопределения ' override 'не переопределял методы базового класса

Ответы [ 3 ]

3 голосов
/ 05 мая 2020

Ключевое слово override может использоваться только , если функция, которую оно заменяет, - virtual. (По сути, это просто «более безопасный» способ указания virtual в производном классе, чтобы вы могли обнаружить случаи, когда нет соответствующей функции базового класса.)

cppreference

Исправление: удалите ключевое слово override (функция базового класса будет по-прежнему переопределена) или добавьте virtual к функции базового класса).

3 голосов
/ 05 мая 2020

MovieRepo::store() не является виртуальной функцией. Спецификатор override работает только с виртуальными функциями. Измените метод базового класса на виртуальный метод, чтобы устранить проблему.

1 голос
/ 05 мая 2020

ключ решения - это ключевое слово virtual .

Спецификатор virtual указывает, что нестатическая c функция-член является виртуальной и поддерживает отправку Dynami c. Он может появляться только в декларативном-спецификаторе-seq начального объявления нестатической c функции-члена (т. Е. Когда он объявлен в определении класса).

См. это для why do we need virtual functions?. С «виртуальным» мы получаем «позднее связывание». Выбор реализации метода определяется во время выполнения в зависимости от типа объекта, на который указывает объект, - от того, как он был изначально создан (а не от типа указателя, через который вы вызываете!).

Если вам нужна такая «поздняя привязка» и вы хотите вызвать правильный метод ( store ) во время выполнения независимо от типа указателя, который вы используете для вызова store () , затем go вперед с виртуальными функциями со следующей реализацией:

Попробуйте следующее:

class MovieRepo {
public:
    // ....
    virtual void store(const Movie& m);
}

class RepoFile: public MovieRepo {
public:
    void store(const Movie& m) override 
    { 
        // ....
    }
}

Подробнее о предупреждении / ошибке компиляции:

Ключевое слово override служит двум целям:

  1. Оно показывает читателю кода, что «это виртуальный метод, который заменяет виртуальный метод базового класса».
  2. Компилятор также знает, что это переопределение, поэтому он может «проверить», что вы не изменяете / не добавляете новые методы, которые, по вашему мнению, являются переопределениями.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...