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