#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 .