C ++ переопределяет абстрактный метод базового класса в самом базовом классе?

Если у меня есть базовый класс как так:

class Base {
public:
Base(){}
virtual void foo()=0;
};

Теперь, если я выведу какой-либо класс из базового класса, он должен будет переопределить foo(),

Что делать, если я хотел поведение на foo() для базового класса тоже? Так что у базового класса есть свой fooи, кроме того, каждый из них должен переопределить foo? Это возможно?

4

Решение

Если вы делаете что-то вроде:

class Base {
public:
Base(){}
virtual void foo() = 0;
};
void Base::foo() {
{
cout << "Hello";
}

вы получите абстрактный класс, так что вы будете не быть в состоянии создать объект b класса Base и заставить его использовать вашу реализацию foo (), вызвав b.foo ().

Так что это не то, что вы хотите! Следующий вопрос: почему вам разрешили предоставить реализацию для Base :: foo, если вы не можете ее использовать? Ну, на самом деле вы можете! Хотя не напрямую.

class Deriv : public Base {
public:
Deriv(){}
virtual void foo();
};
void Deriv::foo()
{
Base::foo(); cout << "  world!";
}

Как вы можете видеть Base :: foo () Можно использоваться производными классами.

Вернемся к вашему вопросу. Ответ ты Можно делать именно то, что вы указали, за исключением того, что базовый класс будет абстрактным.

Альтернатива состоит в том, чтобы делать то, что делает большинство людей, и не указывать = 0, когда вы предоставляете реализацию для foo () в Base. Это означает, что производные классы Можно переопределить foo (), но не иметь к. На самом деле мне кажется, что это имеет смысл: в производных классах, для которых реализация по умолчанию Base :: foo () имеет смысл, вы сохраняете это, но для тех, кому нужно что-то другое, вы переопределяете это.

Обновление: я попытался придумать сценарий, который действительно требует того, о чем спрашивают вопросы, и придумал это:

Представьте, что Document и его производные классы представляют типы документов, и что Document содержит виртуальный метод getClassIcon (), возвращающий URL-адрес файла изображения для значка, представляющего тип документа. Для Document имеет смысл иметь значок (что-то, представляющее общий документ), а также имеет смысл требовать, чтобы все производные классы переопределяли getClassIcon () для предоставления своих собственных значков.

Сказав это, в этом конкретном примере, кажется, легко найти альтернативный дизайн: сделать Document :: getClassIcon () чисто виртуальным методом (= 0) (делая Document абстрактным классом) и добавить OtherDocument в качестве одного из его производных классов, давая Это была реализация getClassIcon Document ранее. PDFDocument, MSWordDocument и т. Д. Все будут необходимы для переопределения getClassIcon () по мере необходимости. То, что этот редизайн может быть использован, чтобы показать, что предыдущий дизайн (поддерживаемый воображаемой версией C ++, которая позволяет то, о чем спрашивает вопрос) связал роль базового класса, Document и роль стоящего класса для документов, которые не принадлежат ни к одному из известных типов, OtherDocument. Конечно, все это в глазах смотрящего 🙂 Можно утверждать, что второй дизайн был просто необходим из-за отсутствия функциональности в языке. Я думаю, что мы думаем (в значительной степени) в соответствии с (компьютерным) языком, на котором мы говорим. 🙂

6

Другие решения

Вы можете предоставить реализацию для чисто виртуального метода:

class Base {
...
virtual void foo()=0;
}

void Base::foo() {
... implementation goes here ...
}

Класс остается абстрактным. Если вы не хотите, чтобы он был абстрактным, вы должны удалить =0, Однако, как только вы это сделаете, вы не сможете заставить производные классы предоставлять свои собственные реализации.

Другими словами, вы должны сделать выбор.

3

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector