Подтвердить что ты не робот

Почему я должен использовать ключевое слово "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;
}
4b9b3361

Ответ 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, которое будет использоваться.