Предупреждение правильное, оно называется «скрытие имени». Переменная типа MyDerivedClass
не может вызвать setValue(SpecialType*)
.
Теперь я собираюсь нагло сорвать
чужой блог :
Перегрузка и скрытие имени в C ++
В телефонном разговоре с Брэдом прошлой ночью он рассказал мне о странной проблеме, с которой он столкнулся в своей новой работе на C ++. Конечно, это не имеет большого значения для людей с обширным опытом работы с C ++, но для тех из нас, кто живет в мире управляемого кода, это казалось странным.
В C ++, когда у вас есть класс с перегруженным методом (функция-член, как бы вы его не вызывали), а затем вы расширяете и переопределяете этот метод, вы должны переопределить все перегруженные методы.
Я понимаю случай, когда вы изменили сигнатуру метода в дочернем классе, тем самым лишив законной силы установленный интерфейс. В этом случае, однако, это кажется нелогичным, поскольку вы не меняете интерфейс, а выборочно переопределяете. Который отличается.
Например:
class FirstClass
{
public:
virtual void MethodA (int);
virtual void MethodA (int, int);
};
void FirstClass::MethodA (int i)
{
std::cout << "ONE!!\n";
}
void FirstClass::MethodA (int i, int j)
{
std::cout << "TWO!!\n";
}
Простой класс здесь с двумя методами (или одним перегруженным методом). Вы хотите переопределить двухпараметрическую версию, поэтому продолжите со следующего:
class SecondClass : public FirstClass
{
public:
void MethodA (int);
};
void SecondClass::MethodA (int i)
{
std::cout << "THREE!!\n";
}
Теперь, когда вы используете экземпляр SecondClass, большинство программистов на Java или C # могут предположить, что вы можете вызвать:
int main ()
{
SecondClass a;
a.MethodA (1);
a.MethodA (1, 1);
}
Однако второй вызов не будет работать, поскольку двухпараметрический метод A не отображается. Вы можете получить указатель и выполнить приведение к FirstClass, но ваш экземпляр SecondClass не наследует не переопределенные методы напрямую.