Первый случай
#include <iostream>
class A
{
public:
virtual void Write(int i)
{
std::wcout << L"Write(int) is called" << std::endl;
}
virtual void Write(wchar_t c)
{
std::wcout << L"Write(wchar_t) is called" << std::endl;
}
};
int _tmain(int argc, wchar_t* argv[])
{
A *p = new A();
int i = 100;
p->Write(i);
return 0;
}
Работает отлично.
Результаты программы
Запись (int) называется
2. Второй случай.
Просто переместите первую функцию в базовый класс:
#include <iostream>
class Base
{
public:
virtual void Write(int i)
{
std::wcout << L"Base::Write(int) is called" << std::endl;
}
};
class Derived: public Base
{
public:
virtual void Write(wchar_t c)
{
std::wcout << L"Derived::Write(wchar_t) is called" << std::endl;
}
};
int _tmain(int argc, wchar_t* argv[])
{
Derived *p = new Derived();
int i = 100;
p->Write(i);
return 0;
}
Результаты программы
Derived :: Write (wchar_t) называется
Но я ожидал, что «Base :: Write (int) называется»
Что не так во втором случае?
Ваш компилятор прав.
Когда вы определяете функцию-член в производном классе, функция-член с тем же именем в базовом классе будет скрытый.
Ты можешь использовать using
чтобы импортировать его в область производного класса, сделайте перегрузку работающей, как вы ожидаете.
class Derived: public Base
{
public:
using Base::Write;
virtual void Write(wchar_t c)
{
std::wcout << L"Derived::Write(wchar_t) is called" << std::endl;
}
};
РЕДАКТИРОВАТЬ
Перегрузка функций не будет проходить через разные области. Когда вы звоните Write
на Derived
, функция-член с именем Write
будет найден на Derived
область видимости, а затем поиск имени остановится, поэтому Write
в Base
никогда не будет рассматриваться для разрешение перегрузки, даже если версия базового класса здесь более уместна.
Увидеть Поиск имени
Я предполагаю, что это потому, что программа находит «более новую» версию функции, которая верна с неявным преобразованием, поэтому она не ищет «лучшую» функцию для вызова в родительском классе.
Я бы предложил:
1) Избегайте перегрузки / переопределения функций с параметрами, которые являются взаимозаменяемыми.
2) Если вы действительно хотите, чтобы вызывался Derived :: Write, используйте:
p->Derived::Write(i);