#c #virtual
#c #виртуальный
Вопрос:
Рассмотрим следующий UML:
Когда я пытаюсь реализовать виртуальную функцию 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 через этот резервный указатель? Возможно ли это вообще? Спасибо 🙂