Почему C ++ не поддерживает перегрузку между областями?

Я считаю, что лучший ответ уже дан здесь: Почему переопределенная функция в производном классе скрывает другие перегрузки базового класса?

Но меня немного смущает, особенно с утверждением:

Чтобы переопределить это поведение, от пользователя требуется явное действие: первоначально переопределение унаследованного метода (ов) (в настоящее время не рекомендуется), теперь явное использование using-декларации.

Предположим, у меня есть следующая программа:

#include <iostream>
using namespace std;
class Base
{
public:
int f(int i)
{
cout << "f(int): ";
return i+3;
}
};
class Derived : public Base
{
public:
double f(double d)
{
cout << "f(double): ";
return d+3.3;
}
};
int main()
{
Derived* dp = new Derived;
cout << dp->f(3) << '\n';
cout << dp->f(3.3) << '\n';
delete dp;
return 0;
}

У меня есть два вопроса:

  1. Могу ли я предположить, что объект производного класса w.r.t int f(int i) Функция не существует вообще. Это не наследуется из-за сокрытия имени.

  2. Если мне нужно использовать эту функцию в производном классе, я должен снова определить ее в производном классе?

1

Решение

  1. Могу ли я предположить, что при производном объекте класса w.r.t функция int f (int i) вообще не существует. Это не наследуется из-за сокрытия имени.

Это является по наследству, это просто … скрытый, не может быть найден, если вы не указали область действия (поиск безусловного имени. Вы можете указать это явно с помощью оператора разрешения области :: (поиск подходящего имени):

dp->Base::f(3);
  1. Если мне нужно использовать эту функцию в производном классе, я должен снова определить ее в производном классе?

Как сказано в цитируемом ответе, вы можете сделать это с «явным использованием using-декларации».

class Derived : public Base
{
public:
using Base::f;
...
};

РЕДАКТИРОВАТЬ (для дополнительных вопросов из комментария)

  1. Если это имя скрыто, значит, я могу объявить его снова? То же имя, те же параметры?

Да, ты можешь. Это все еще имя, скрывающее.

  1. Если да, то что, если я также добавил using Base::f вместе с новой декларацией? Это приведет к двойному определению?

Нет, это не двойное определение. Использование декларации просто вводит имя в область производного класса. И функция-член, объявленная в производном классе, будет скрывать ту, что была введена из базового класса, но она по-прежнему скрывает имя. (Обратите внимание, что вы все еще можете вызвать один из базового класса по dp->Base::f(3);.)

Если у производного класса уже есть член с тем же именем, списком параметров и квалификациями, член производного класса скрывает или переопределяет (не конфликтует) член, представленный в базовом классе.

4

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

Других решений пока нет …

По вопросам рекламы [email protected]