C Перегруженная функция и подклассы

#c #oop #polymorphism #overloading

#c #ооп #полиморфизм #перегрузка

Вопрос:

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

 struct Vehicle {...}
struct Car : public Vehicle {...}

string A(Vehicle *v) { return "vehicle"; }
string A(Car *c) { return "car"; }
  

И я делаю это:

 Vehicle *v = new Car();
cout << A(v);
  

Почему компилятор выводит «транспортное средство»? В конце концов, v указывает на объект Car.

Комментарии:

1. Вы пытались запустить ее, чтобы посмотреть, что произойдет?

2. Вы пробовали ее компилировать? Должно быть как минимум предупреждение…

3. Определенно -1 по этому вопросу — мог бы быть мгновенно решен с минутными усилиями с помощью компилятора.

4. @Doug @Flinsch @DeadMG, меня не интересует, что делает компилятор. Мне интересно узнать, что говорится в спецификации C и почему. например, это может быть неопределенным.

5. За исключением того, что ни одна реализация не соответствует чему-либо подобному.

Ответ №1:

Перегруженная функция A(Vehicle*) лучше подходит для аргумента типа Vehicle* . Таким образом, cout будет выводиться:

 vehicle
  

Объяснение:

Разрешение перегруженной функции выполняется на основе статического типа аргумента. И статический тип аргумента v является Vehicle* . Следовательно, будет вызвана функция A(Vehicle*) .

Ответ №2:

Это пример статического связывания. Во время компиляции становится ясно, что string A(Vehicle *v) функция будет вызвана. Конечно, «транспортное средство» должно быть в выходных данных.

Ответ №3:

 "vehicle" 
  

распечатывается

Это происходит потому, что статический тип v является транспортным средством. Таким образом, A, определенное для Vehicle, используется компилятором.

Компилятор использует информацию о динамическом типе при вызове функции-члена для выполнения вызовов виртуальных методов. Ключевое слово virtual обязательно. В этом случае указатель «this» будет соответствующим образом понижен на соответствующем уровне переопределения.

Однако, за исключением этого особого случая, компилятор не будет выполнять понижение для вас без явного dynamic_cast .