Страницы

Поиск по вопросам

вторник, 9 апреля 2019 г.

Рекурсия вызваная из базового класса

Все мы знаем обычную рекурсию, например:
функция имя(){ условие_завершения; имя(); }
Понятно что эта функция будет существовать в памяти в нескольких экземплярах до завершения всей цепочки вызовов.
Встретил вот такой код:
class SimpleDelegate : public QStyledItemDelegate { public: void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index ) const ...... условие_выхода ...... { QStyledItemDelegate::paint(pPainter, option, index); // рекурсия ? } };
Вроде бы тоже рекурсия но как она работает? То ли копия базового объекта создается то ли просто метод дублируется для текущего объекта, то ли.. , в общем не понятно.


Ответ

В данном определении функции-члена класса рекурсии нет
class SimpleDelegate : public QStyledItemDelegate { public: void paint(QPainter* pPainter, const QStyleOptionViewItem& option, const QModelIndex& index ) const ...... условие_выхода ...... { QStyledItemDelegate::paint(pPainter, option, index); // рекурсия ? } };
Имеются две различные функции. Одна функция - это SimpleDelegate::paint , другая функция - это QStyledItemDelegate::paint
Первая функция в области определения производного класса скрывает объявление второй функции с тем же самым именем в базовом классе. Поэтому если вы хотите из функции производного класса вызвать одноименную функцию базового класса, то вам нужно указывать ее квалифицированное имя, что и делается в приведенном примере.
Рассмотрите данную демонстрационную программу
#include #include
int main() { struct A { void f(const char *) const { std::cout << "Hello"; } void f(char) const { std::cout << ' '; } };
struct B : A { void f(const std::string &s ) const { A::f(nullptr); A::f(' '); std::cout << s << std::endl; } };
B().f(std::string("perfect"));
return 0; }
Ее вывод на консоль
Hello perfect
Здесь функция, объявленная в производном классе B скрывает одноименные функции, объявленные в базовом классе A. Поэтому чтобы обратиться к этим функциям базового класса в области определения производного класса, следует использовать квалифицированные имена функций базового класса.
Другой альтернативный подход при условии, что нет неоднозначности в перегрузке функций, это использовать using объявления в производном классе. Например,
struct B : A { using A::f; void f(const std::string &s ) const { f(nullptr); f(' '); std::cout << s << std::endl; } };
Однако, если сигнатуры одноименных функций в базовом и производном классах совпадают, то, чтобы исключить неоднозначность, придется явно указывать квалифицированные имена функций для базового класса.

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

Отправить комментарий