Pull to refresh
34
0
Георгий Баркан @h1ppo

User

Send message
Вы исходите из того, что значение параметра по умолчанию должно быть подставлено компилятором. Абсолютно верно с точки зрения требований стандарта.

Откуда это требование появилось — вот в чем вопрос!

На мой взгляд, нужно было либо потребовать виртуализировать значения по умолчанию вместе с виртуальными функциями (это, конечно, слабо реально учитывая требования эффективности и т. п.), либо запретить их прописывать в переопределении виртуальной функции (B:foo).
Про Майерса согласен с Вами, стоило мне его упомянуть. И разъяснили Вы все верно.

Вопрос, на который я не могу найти пока ответа, почему Страуструп с коллегами не запретили параметры по умолчанию в виртуальных функциях. Или уж, по-крайней мере, не потребовали от компиляторов следить за тем, чтобы дефолтные значения уже нельзя было прописать в производном классе.

Ну ладно в стандарте 1997 года. Книжка Майерса вышла в 1996-ом, еще не все успели прочесть :) Но к 2009-ому уж можно было бы озаботиться этой банальной проблемой?

Я еще одна загадка — почему компиляторы отмалчиваются на этот счет.
Вы все безусловно верно написали!

Единственное маленькое уточнение, стандарт языка никак не регламентирует устройство механизма вызова виртуальных функций. Вполне допустима реализация компилятора, которая вообще не будет создавать таблиц указателей виртуальных функций, а, например, (моя чистая умозрительная спекуляция) будет работать через какой-нибудь глобальный объект-словарь. Никому в здравом уме это в голову не придет, но ничего незаконного в этом нет.

Соответственно механизм, который находит адрес соответствующей виртуальной функции для выполнения, мог бы быть расширен для хранения и значений параметров по умолчанию. Например, в vtable положить не только адреса функций, а и значения по умолчанию рядышком, как в стеке вызова.

Тем не менее, авторы стандарта языка сознательно пошли на отказ от «виртуализации» значений по умолчанию. Т.е. их «невиртуальное» поведение является обязательным с точки зрения стандарта (см. тот пункт из стандарта, который я указал в тексте хабратопика).

То есть, текущее поведение компилятора отнюдь не является чем-то единственно принципиально возможным. Если бы не странное требование стандарта, вполне могло быть и по-другому. (Правда с этим не согласны поборники принципа «значения по умолчанию — часть интерфейса, а не реализации».)
Допустим, что инициализация параметров по умолчанию должна быть частью интерфейса, а не реализации. Почему язык мне вообще разрешает в таком случае прописать параметр по умолчанию в классе реализации?
Ну… в C# 4.0 они передумали :) и там все очень чудесато получилось. Забавно пронаблюдать, как мнение Андерса Хейсльберга по этому вопросу плавно эволюционировало.

А в Java их действительно нет (пока??) и опять же интересно мнение коммъюнити на эту тему и обоснование дизайнеров языка.
Да кто бы спорил! В моем личном списке правил кодирования на это вообще жесткий запрет (виртуальная функция с параметрами по умолчанию).

Философский вопрос тут возникает, а правильно ли устроена вселенная, если при полном отсутствии каких-либо напрягов в стандарте языка и у компиляторов по поводу этой ситуации приходится такое жесткое правило себе придумывать… Сделаю еще топик по поводу C# и Java — там все тоже очень интересно происходит.
Ну не только для шаблонов, еще очень многие любят, например, конструкторы снабжать большим числом параметров, но со значениями по умолчанию. К счастью конструкторы не бывают виртуальными.

Согласен с Вами, что в виртуальных функциях их просто нельзя использовать. Вопрос напрашивается, почему в языке не запретили такое использование. Разрешили бы только для невиртуальных функций, например.
Тогда все ОК, если, конечно, вы в ответ не подглядывали :) По моему опыту не больше 10% людей с опытом работы на C++ уверенно дают правильный ответ.
У меня же не было цели тестировать хабрапользователей :)

Важно для себя сначала понять какая функция вызвана, если B::Foo, то Вы дали верный ответ.

Но довольно часто отвечают A::Foo, n = 10. Это значит, что у разработчик не понимает, что такое виртуальные функции. Сначала надо с ними разобраться, а тогда станет понятен в чем прикол этого примера.

Это у меня была любимая задачка на собеседовании для разработчиков C++ с опытом выше среднего.
2

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Works in
Date of birth
Registered
Activity