Абстрактный класс и чистый метод C++
Я прочитал в книге Стивена Прата - "C++ Primer Plus VI Edition", что в абстрактном классе я могу написать определение чистого метода. Я понял что могу написать например void pure() = 0
и тогда я могу дать определение этого метода в этом классе. я думал так = 0
только для того, чтобы сделать класс абстрактным, и если я создаю другой класс, унаследованный от этого класса, мне не нужно его перезаписывать (я не знаю, правильно ли слово "перезаписать", я имел в виду, что не хочу скрывать метод из базового класса, написав метод с тем же именем во втором классе).
Я проверил это в компиляторе, и я получил предупреждение, что "у него нет переопределения". Итак, если мне нужно перезаписать этот чистый виртуальный метод (с определением в абстрактном классе) во вторичном классе, как я могу использовать это определение из базового класса? Это бесполезно?
3 ответа
Вы ищете что-то вроде этого:
class Abstract {
public:
virtual void f() = 0;
};
// A pure virtual function can still be defined.
// It has to be defined out-of-class.
void Abstract::f() {
// Do something
}
class Concrete : public Abstract {
public:
void f() {
Abstract::f(); // call base class implementation
// Do something more
}
};
Вот пример, который объясняет понятие чистых функций
#include <iostream>
struct A
{
virtual ~A() = default;
virtual void what() const = 0;
};
void A::what() const
{
std::cout << "struct A";
}
struct B : A
{
virtual void what() const = 0;
};
void B::what() const
{
A::what();
std::cout << ", struct B : A";
}
struct C : B
{
void what() const;
};
void C::what() const
{
B::what();
std::cout << ", struct C: B";
}
int main()
{
// A a; compiler error
// B b; compiler error
C c;
const A &rc = c;
rc.what();
std::cout << std::endl;
return 0;
}
Выход программы
struct A, struct B : A, struct C: B
В этом примере классы A и B являются абстрактными, потому что они имеют чисто виртуальную функцию, хотя каждый из них предоставляет соответствующее определение своей чисто виртуальной функции.
И только класс C не является абстрактным, потому что он объявляет виртуальную функцию как не чистую виртуальную функцию.
Если вы хотите создать экземпляр унаследованного класса, то есть создать объект этого типа, вы должны иметь все чистые виртуальные методы, реализованные в унаследованном классе.
Другими словами, чисто виртуальные методы не только определяют интерфейс класса, но также вынуждают вас предоставлять их фактическую реализацию.