Почему я должен использовать ключевое слово "using" для доступа к методу базового класса?
Я написал код ниже, чтобы объяснить мою проблему. Если я прокомментирую строку 11 (с ключевым словом "using" ), компилятор не скомпилирует файл и не отобразит эту ошибку: invalid conversion from 'char' to 'const char*'
. Кажется, что не существует метода void action(char)
класса Parent
в классе Son
.
Почему компилятор ведет себя так? Или я сделал что-то не так?
class Parent
{
public:
virtual void action( const char how ){ this->action( &how ); }
virtual void action( const char * how ) = 0;
};
class Son : public Parent
{
public:
using Parent::action; // Why should i write this line?
void action( const char * how ){ printf( "Action: %c\n", *how ); }
};
int main( int argc, char** argv )
{
Son s = Son();
s.action( 'a' );
return 0;
}
Ответы
Ответ 1
Объявленный в производном классе action
скрывает action
, объявленный в базовом классе. Если вы используете action
в объекте Son
, компилятор будет искать в методах, объявленных в Son
, найти один из них с именем action
и использовать его. Он не будет продолжать поиск в методах базового класса, так как он уже нашел подходящее имя.
Затем этот метод не соответствует параметрам вызова, и вы получаете сообщение об ошибке.
См. также Часто задаваемые вопросы по С++ для получения дополнительных разъяснений по этой теме.
Ответ 2
Удивительно, но это стандартное поведение. Если производный класс объявляет метод с тем же именем, что и метод, определенный базовым классом, метод производного класса скрывает базовый класс.
См. Часто задаваемые вопросы по С++
Ответ 3
Заметка: необходимость использования "использования" в этой ситуации - это красный флаг, который может привести к запутыванию вашего кода для других разработчиков (в конце концов, это путало компилятор!). Вероятно, вы должны переименовать один из двух методов, чтобы сделать различие понятным для других программистов.
Одна возможность:
void action( const char how )
{
takeAction( &how );
}
void action( const char * how )
{
takeAction(how);
}
virtual void takeAction(const char * how) = 0;
Ответ 4
Если в производном классе переопределяется любая загруженная функция, то вся перегруженная функция в базовом классе скрыта.
Один из способов включить обе функции - избежать перегрузки функций в классах. или
Вы можете использовать ключевое слово using
, которое будет использоваться.