Все мы знаем обычную рекурсию, например:
функция имя(){
условие_завершения;
имя();
}
Понятно что эта функция будет существовать в памяти в нескольких экземплярах до завершения всей цепочки вызовов.
Встретил вот такой код:
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
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;
}
};
Однако, если сигнатуры одноименных функций в базовом и производном классах совпадают, то, чтобы исключить неоднозначность, придется явно указывать квалифицированные имена функций для базового класса.
Комментариев нет:
Отправить комментарий