Как реализовать виртуальную функцию в производном классе?

#c #virtual

#c #виртуальный

Вопрос:

Рассмотрим следующий UML:

UML для 4 классов

Когда я пытаюсь реализовать виртуальную функцию rate() в Single.cpp , я получаю сообщение об ошибке: невозможно выделить объект абстрактного типа ‘Single’
Booking* b = new Single();

изображение ошибки, которую я получаю

addBooking() Функция должна создать указатель Single типа Booking of , добавить указатель на QList ( BookingList производный от QList<Booking*> ) и вернуть Booking указатель.

Когда я закомментирую виртуальную функцию, все работает. Почему это происходит и как я могу это исправить?

Ниже приведена минимальная версия моей программы:

 #ifndef BOOKING_H
#define BOOKING_H

class Booking
{
public:
    Booking();
    double SINGLE_PPPN = 200.00;
    virtual double rate() = 0;
};

#endif // BOOKING_H
  
 #include "booking.h"

Booking::Booking()
{
}
  
 #ifndef BOOKINGLIST_H
#define BOOKINGLIST_H
#include <QList>
#include <iostream>
#include "booking.h"
#include "single.h"

using namespace std;

class BookingList : public QList<Booking*>
{
public:
    BookingList();
    Booking* addBooking();
    void deleteAll();
};

#endif // BOOKINGLIST_H
  
 #include "bookinglist.h"

BookingList::BookingList()
{
}

Booking* BookingList::addBooking()
{
    Booking* b = new Single();

    this->append(b);

    cout << "Total bookings: " << this->size() << "nn" <<endl;

    return b;
}

void BookingList::deleteAll()
{
    for (int i = 0; i < this->count(); i  )
    {
        cout << "Deleting Item At: " << i << endl;
        delete this->at(i);
    }
}
  
 #ifndef SINGLE_H
#define SINGLE_H
#include "booking.h"

class Single : public Booking
{
public:
    Single();
};

#endif // SINGLE_H
  
 #include "single.h"

Single::Single()
{
}

double Single::rate()
{
    return Booking::SINGLE_PPPN;
}
  
 #include <QCoreApplication>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    return a.exec();
}
  

Комментарии:

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

2. вы должны добавить переопределенное объявление функции «rate ()» в заголовок «single.h»

3. Пожалуйста, добавьте сообщение об ошибке в виде текста к вашему вопросу, чтобы следующий пользователь с той же ошибкой мог найти это.

Ответ №1:

Вам нужно объявить свой метод override в определении класса

 class Single : public Booking
{
public:
    Single();
    double rate() override;  // this line
};
  

затем вы можете фактически реализовать метод в своем cpp-файле, как вы это делали

 double Single::rate()
{
    return Booking::SINGLE_PPPN;
}
  

Комментарии:

1. override Спецификатор является хорошей практикой (по крайней мере, начиная с C 11), но технически необязателен. Минимальное требование состоит в том, чтобы функция была объявлена в производном классе с теми же типами аргументов, типом возвращаемого значения и совместимой спецификацией исключения. override Спецификатор помогает выявить некоторые проблемы (например, если унаследованной функции нет virtual в базовом классе).

2. Что подразумевается под совместимой спецификацией исключения?

3. @ClintTheron это означает, объявлена ли функция noexcept

4. Booking — это суперкласс Single, а BookingList добавляет одиночные указатели типа Booking в QList. В моем клиенте я создаю экземпляр BookList и вызываю addBooking, который возвращает указатель бронирования. Когда я вызываю методы для этого указателя бронирования, я получаю только методы бронирования. Как мне получить доступ к методам Single через этот резервный указатель? Возможно ли это вообще? Спасибо 🙂