Re[3]: Тест по ООП и С++. Есть соображения?
От: LaptevVV Россия  
Дата: 26.11.04 06:22
Оценка: 9 (1)
Здравствуйте, 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>Вообще некоторые вопросы смахивают не на общепризнанное знание, а на знание лекций конкретого преподавателя.

Только последний

Остальные — должен знать каждый студент. Другое дело, что порядок вопросов — да. соответствует главе "Наследование" в лекциях.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.