Здравствуйте, Alexey_VL, Вы писали:
A_V>Здравствуйте, Dr.Gigabit, Вы писали:
DG>>Hello all!
DG>>Решил я сделать тест, по типу Brainbench, связанный с ООП и его реализации в С++ (ну как обычно, синтаксис, классы, наследование, перегрузка и т.д.) DG>>Может быть у кого есть интересные вопросы? Основное требование : вопросы должны затрагивать действительно те вещи, который программист на C++ должен(обязан?) знать, желательно, чтобы вопрос занимал не много строк кода, а так же, что бы к нему можно было придумать варианты ответа.
DG>>Вообщем, был бы очень благодарен. Потом при желании можно сделать и на RSDN on-line версию такого тестирования.
A_V>Вот. Не совсем тест в общем-то — на самом деле это на 99% краткое содержание справочника по С++ Шилдта — я по нему С++ учил, а вопросы типа для повторения. A_V> Могу кинуть на мыло в вордовском формате.
Здравствуйте, Dr.Gigabit, Вы писали:
DG>Если не сложно на dr.gigabit@tut.by.
Скинул, но еще раз повторюсь — к этим вопросам имеет смысл книжку Шилдта "Полный справочник по С++" купить, иначе некоторые вопросы малость непонятны.
DG>А с последней задачей, имхо, перебор
Ну, эт на любителя
Мафиозная диктатура это нестабильность. Если не мафиозная диктатура, то Конституция и демократия.
LVV>Класс! LVV>Сначала A из конструктора, потом Х из последнего обработчика, а потом должна С из деструктора. Причем С — на новой строке, так как после выхода из обработчика сработает endl
Деструктор guard будет вызван при выходе из его области видимости, до входа в обработчик исключительной ситуации. Т.е. вывод программы должен быть ACX.
Здравствуйте, Alexey_VL, Вы писали:
A_V>Да, еще вдогонку пара задачек:
A_V>int x = 5;
A_V>Какой будет результат в случаях: A_V>1. x = x+++x; A_V>2. x = x+++++x; A_V>3. x = x+++++++x; A_V>4. ++x = x+++++x; A_V>5. x++ = x+++++x; A_V>
А это видимо вопросы для собеседования программистов с даром предвидения
Здравствуйте, LaptevVV, Вы писали:
P>>Сейчас пытаюсь наладить тестирование уровня контрагентов. P>>Как вам нравятся такие задания (не только про ООП): P>>4. Как улучшить P>> assert( ::CloseHandle(x) ); LVV>Не совсем понял вопрос. Что значит "улучшить"? LVV>::CloseHandle(x) очевидно выдает некий результат-число (надо в справочнике смотреть — это ж функция API)
Вся соль не в ::CloseHandle(x), а в assert(...) — это макрос, который в release версии приложения разворачивается в (void)(0) — т.е. вызова ::CloseHandle(x) не произойдет.
P>>5. Определить, не компилируя, что напечатает программа
LVV>Класс! LVV>Сначала A из конструктора, потом Х из последнего обработчика, а потом должна С из деструктора. Причем С — на новой строке, так как после выхода из обработчика сработает endl
Нет, не верно. Программа напечатает "ACX<endl>". Объект guard разрушится в момент выхода из области видимости, а момент этот наступает при выбросе исключения (throw 0).
По пятому вопросу:
Выполнение кода с обработкой исключений имеет некоторые особенности на разных платформах, например Borland не возбуждает исключение при делении на ноль, а у VC6 есть ключи компиляции и в некоторых экзотических случаях можно получить самых разных чертей: от несрабатывания деструктора локального объекта до неперехвата исключения. То есть, если бы вместо throw было бы int a=0; a = 1/a;, то вопрос был бы очень некорректным.
Но я был уверен, что тут все честно и по стандарту.
Остальные замечания может бросить на RSDN Bench?
Здравствуйте, Paranoik, Вы писали:
P>Здравствуйте, LaptevVV, Вы писали:
P>>>Как вам нравятся такие задания (не только про ООП): P>>>4. Как улучшить P>>> assert( ::CloseHandle(x) ); LVV>>Не совсем понял вопрос. Что значит "улучшить"? LVV>>::CloseHandle(x) очевидно выдает некий результат-число (надо в справочнике смотреть — это ж функция API)
P>Только в релизе она вызвана не будет...
Ну да, этож assert!
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
LVV>>Класс! LVV>>Сначала A из конструктора, потом Х из последнего обработчика, а потом должна С из деструктора. Причем С — на новой строке, так как после выхода из обработчика сработает endl
K>Деструктор guard будет вызван при выходе из его области видимости, до входа в обработчик исключительной ситуации. Т.е. вывод программы должен быть ACX.
Да, похоже на то — он же внутри блока объявлен.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, Igor Karablin, Вы писали:
IK>Здравствуйте, LaptevVV, Вы писали:
P>>>Сейчас пытаюсь наладить тестирование уровня контрагентов. P>>>Как вам нравятся такие задания (не только про ООП): P>>>4. Как улучшить P>>> assert( ::CloseHandle(x) ); LVV>>Не совсем понял вопрос. Что значит "улучшить"? LVV>>::CloseHandle(x) очевидно выдает некий результат-число (надо в справочнике смотреть — это ж функция API) IK>Вся соль не в ::CloseHandle(x), а в assert(...) — это макрос, который в release версии приложения разворачивается в (void)(0) — т.е. вызова ::CloseHandle(x) не произойдет.
Океюшки. Тогда вопрос надо несколько поменять, а то я не понял, что улучшать-то? P>>>5. Определить, не компилируя, что напечатает программа IK>
LVV>>Класс! LVV>>Сначала A из конструктора, потом Х из последнего обработчика, а потом должна С из деструктора. Причем С — на новой строке, так как после выхода из обработчика сработает endl IK>Нет, не верно. Программа напечатает "ACX<endl>". Объект guard разрушится в момент выхода из области видимости, а момент этот наступает при выбросе исключения (throw 0).
Да, это я не обратил внимание. Правильно.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
LVV>11. Сформулируйте принцип подстановки.
? LVV>13. Объясните, что такое "срезка" или "расщепление".
? LVV>23. Может ли конструктор быть виртуальным? А деструктор?
По поводу конструктора интересен ответ. Какова Ваша религия ? LVV>34. Приведите классификацию целей наследования.
Приведите плз.
Вообще некоторые вопросы смахивают не на общепризнанное знание, а на знание лекций конкретого преподавателя.
Здравствуйте, s.ts, Вы писали:
ST>Здравствуйте, LaptevVV, Вы писали:
LVV>>11. Сформулируйте принцип подстановки. ST>?
Впервые его сформулировала Барбара Лисков
Ответ из моей книжки
Открытое наследование устанавливает между классами отношение "является": класс-наследник является разновидностью класса-родителя. И это не просто словесная формулировка — она непосредственно поддерживается компилятором. Когда мы пишем, что класс Derived (производный) открыто наследует от класса Base (базовый), мы сообщаем компилятору, что каждый объект типа Derived является также объектом класса Base. С практической точки зрения это означает, что везде, где может быть использован объект типа Base, вместо него разрешается подставлять объект типа Derived — это и есть принцип подстановки.
Этот принцип работает и для ссылок, и для указателей: вместо ссылки (указателя) на базовый класс может быть подставлена ссылка (указатель) на класс-наследник. Преобразование типа при этом прописывать не обязательно — оно выполняется автоматически. Эккель называет такое приведение типов повышающим.
Обратное — неверно! Например, будильник является часами, но не всякие часы — будильник. Здесь часы — базовый класс, а будильник — производный.
LVV>>13. Объясните, что такое "срезка" или "расщепление". ST>?
Коротко — в производном классе могут быть определены дополнительные поля. Во время присваивания при преобразовании по принципу подстановки "лишние поля в объект базового класса. естественно, не попадают.
Чтобы понять, в чем дело, обратимся к классам точек. Рассмотрим простой пример с двумерными и трехмерными точками.
Point3D b(1,2,3);
Point2D a = b; // подстановка в конструкторе копирования - срезка
a = b; // подстановка в присваивании - срезка
Работает принцип подстановки, однако нас поджидает неприятность: так как базовый класс ничего не знает о своих наследниках, то в переменную a копируется только Point2D-часть трехмерной точки. Этот эффект называется срезкой [Страуструп] или расщеплением [Брюс Эккель]; он частенько приводит к ошибкам. Например, при передаче параметра по значению, как мы знаем, работает конструктор копирования, поэтому в таких случаях тоже может произойти срезка. При передаче параметра по ссылке (или по указателю) ничего подобного не происходит.
LVV>>23. Может ли конструктор быть виртуальным? А деструктор? ST>По поводу конструктора интересен ответ. Какова Ваша религия ?
Синтаксически это запрещено стандартом. Однако можно определить виртуальную производящую (термин Элджера) функцию. Эту функцию и можно назвать виртуальным конструктором, так как ее назначение — сконструировать объект. Идиома виртуального конструктора — основа паттерна Фабрика LVV>>34. Приведите классификацию целей наследования. ST>Приведите плз.
Тимоти Бадд приводит интересную классификацию форм наследования. Форма наследования определяет — для чего, с какой целью используется наследование. Бадд считает, что порождение дочернего класса может быть выполнено по следующим причинам:
специализация. Класс-наследник является специализированной формой родительского класса — в наследнике просто переопределяются методы. Принцип подстановки выполняется. Очевидно, что такая форма наследования в С++ реализуется простым открытым наследованием. Примером является наследование часы -> будильник;
спецификация. Дочерний класс реализует поведение, описанное в родительском классе. Ясно, что в С++ такая форма реализуется простым открытым наследованием от абстрактного класса;
конструирование. Класс-наследник использует методы базового класса, но не является его подтипом (принцип подстановки не выполняется). В С++ такую форму можно реализовать простым закрытым наследованием;
расширение. В класс-потомок добавляют новые методы, расширяя поведение родительского класса. Хотя Т. Бадд выделяет эту форму наследования в отдельный вид, однако, на мой взгляд, она мало отличается от специализации, особенно учитывая то, что принцип подстановки в такой форме выполняется;
обобщение. Дочерний класс обобщает поведение базового класса. Обычно такое наследование используется в тех случаях, когда мы не можем изменить поведение базового класса (например, базовый класс является библиотечным классом);
ограничение. Класс-наследник ограничивает поведение родительского класса. Очевидно, что в С++ такой вид наследования реализуется простым закрытым наследованием (пример — TUniversalDeque -> TStack );
варьирование. Базовый класс и класс-потомок являются вариациями на одну тему, однако связь "класс-подкласс" произвольна, например, "квадрат-прямоугольник" или "прямоугольник-квадрат". Этот форму наследования лучше не применять;
комбинирование. Дочерний класс наследует черты нескольких классов — это множественное наследование.
ST>Вообще некоторые вопросы смахивают не на общепризнанное знание, а на знание лекций конкретого преподавателя.
Только последний
Остальные — должен знать каждый студент. Другое дело, что порядок вопросов — да. соответствует главе "Наследование" в лекциях.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, Alexey_VL, Вы писали:
A_V>Да, еще вдогонку пара задачек:
A_V>int x = 5;
A_V>Какой будет результат в случаях: A_V>1. x = x+++x; A_V>2. x = x+++++x; A_V>3. x = x+++++++x; A_V>4. ++x = x+++++x; A_V>5. x++ = x+++++x; A_V>
Ответ стандарта: undefined behaviour — неопределенное поведение!
Во всех случаях, что бы там не выдавали компиляторы.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
LVV>Здравствуйте, Alexey_VL, Вы писали:
A_V>>Да, еще вдогонку пара задачек:
A_V>>int x = 5;
A_V>>Какой будет результат в случаях: A_V>>1. x = x+++x; A_V>>2. x = x+++++x; A_V>>3. x = x+++++++x; A_V>>4. ++x = x+++++x; A_V>>5. x++ = x+++++x; A_V>> LVV>Ответ стандарта: undefined behaviour — неопределенное поведение! LVV>Во всех случаях, что бы там не выдавали компиляторы.
Честно говоря, я не знаток стандарта, поэтому хотелось бы конкретики. Пример построен на таблице приоритетов и грамматике С++. Думаю, что они входят в стандарт. Меня в плане неопределенности только пятый пример смущает — почему компилятор не хочет принимать х++ как lvalue.
Мафиозная диктатура это нестабильность. Если не мафиозная диктатура, то Конституция и демократия.
Здравствуйте, Alexey_VL, Вы писали:
A_V>>>Да, еще вдогонку пара задачек:
A_V>>>int x = 5;
A_V>>>Какой будет результат в случаях: A_V>>>1. x = x+++x; A_V>>>2. x = x+++++x; A_V>>>3. x = x+++++++x; A_V>>>4. ++x = x+++++x; A_V>>>5. x++ = x+++++x; A_V>>> LVV>>Ответ стандарта: undefined behaviour — неопределенное поведение! LVV>>Во всех случаях, что бы там не выдавали компиляторы.
A_V>Честно говоря, я не знаток стандарта, поэтому хотелось бы конкретики. Пример построен на таблице приоритетов и грамматике С++. Думаю, что они входят в стандарт. Меня в плане неопределенности только пятый пример смущает — почему компилятор не хочет принимать х++ как lvalue.
Для пунктов 2-5 компилятор должен выдать ошибку потому что x++ не является lvalue, а следовательно к нему неприменимы операции ++ и =. Читать здесь
П.1 должен скомпилироваться, но мы получим неопределенное поведение, потому что для встроенных типов все операции в выражении x++ + x производятся как-бы одновременно, и для int x = 5 можем получить как 5 + 6, так и 5 + 5.
Здравствуйте, Alexey_VL, Вы писали:
LVV>>Ответ стандарта: undefined behaviour — неопределенное поведение! LVV>>Во всех случаях, что бы там не выдавали компиляторы.
A_V>Честно говоря, я не знаток стандарта, поэтому хотелось бы конкретики. Пример построен на таблице приоритетов и грамматике С++. Думаю, что они входят в стандарт. Меня в плане неопределенности только пятый пример смущает — почему компилятор не хочет принимать х++ как lvalue.
Зайди в поиск и набери строку "чудеса инкремента" — тема обсосана до костей и очень подробно...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, Astaroth, Вы писали:
A>Здравствуйте, Dr.Gigabit, Вы писали:
DG>>Не завидую я вашим студентам
A>Мне бы такого препода...
Эх!!! Пообсуждали бы!....
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, folk, Вы писали:
F>Здравствуйте, Alexey_VL, Вы писали:
A_V>>>>Да, еще вдогонку пара задачек:
A_V>>>>int x = 5;
A_V>>>>Какой будет результат в случаях: A_V>>>>1. x = x+++x; A_V>>>>2. x = x+++++x; A_V>>>>3. x = x+++++++x; A_V>>>>4. ++x = x+++++x; A_V>>>>5. x++ = x+++++x; A_V>>>> LVV>>>Ответ стандарта: undefined behaviour — неопределенное поведение! LVV>>>Во всех случаях, что бы там не выдавали компиляторы.
Это, конечно, не совсем правильно..
1. x = x++ + x; // неопределенное поведение. Ошибок компиляции не должно быть
2. x = x++ + ++x; // неопределенное поведение. Ошибок компиляции не должно быть
3. x = x++++ + ++x; // Должна быть ошибка компиляции для х++++.
Постфиксный инкремент выдает значение, поэтому не транслируется даже (х++)++. А вот (++х)++ = работает.
4. ++x = x++ + ++x; // неопределенное поведение. Ошибок компиляции не должно быть.
Префикный инкремент выдает ссылку, поэтому так писать можно...
5. x++ = x++ + ++x; // Должна быть ошибка компиляции для х++ слева — это не l-value
F>Для пунктов 2-5 компилятор должен выдать ошибку потому что x++ не является lvalue, а следовательно к нему неприменимы операции ++ и =. Читать здесь
Здравствуйте, LaptevVV, Вы писали:
A>>Мне бы такого препода... LVV>Эх!!! Пообсуждали бы!....
Да не, правда.
Специальность — прикладная математика. Я на 3м курсе. Предметы, по которым требовалось бы делание хоть чего-нибудь за компом, кончились в первом семестре второго курса, начнутся снова где-то в районе диплома. 80% тех, кто учится в моей и параллельных группах, ни на что бОльшее, чем hello world, не способны. Болото...
Здравствуйте, Astaroth, Вы писали:
A>Здравствуйте, LaptevVV, Вы писали:
A>>>Мне бы такого препода... LVV>>Эх!!! Пообсуждали бы!....
A>Да не, правда. A>Специальность — прикладная математика. Я на 3м курсе. Предметы, по которым требовалось бы делание хоть чего-нибудь за компом, кончились в первом семестре второго курса, начнутся снова где-то в районе диплома. 80% тех, кто учится в моей и параллельных группах, ни на что бОльшее, чем hello world, не способны. Болото...
A>ВУЗ — МИРЭА.
Ну, тогда дело не в преподе, а в учебном плане твоей специальности...
Более программистской нет поблизости?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!