Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Мизрохи С.В. -> "Turbo Pascal и объектно-ориентированное программирование" -> 64

Turbo Pascal и объектно-ориентированное программирование - Мизрохи С.В.

Мизрохи С.В. Turbo Pascal и объектно-ориентированное программирование — М.: Финансы и статистика , 1992. — 192 c.
ISBN 5-279-00903-2
Скачать (прямая ссылка): efektispolzc2000.djvu
Предыдущая << 1 .. 58 59 60 61 62 63 < 64 > 65 66 67 68 69 70 .. 105 >> Следующая

Конечно, в какой-то момент времени должны быть реализованы конкретные классы, поддерживающие интерфейс класса-протокола, и вызваны настоящие конструкторы. Все это скрыто внутри файлов, реализующих виртуальные конструкторы. Например, класс-протокол Person мог бы иметь конкретный производный класс Real Person, обеспечивающий реализацию наследуемых виртуальных функций:
class RealPerson: public Person { public:
RealPerson (const strings name, const Dates birthday,
const AddressS addr, const CountryS country) : name_(name), birthday_(birthday), address_(addr), country_(country)
O
EQEI ^¦HII ИНГ Классы и функции: реализация
Теперь, я уверен, вы ждете примечания мелким шрифтом: «Во сколько обойдется этот хитрый фокус». Цена вполне обычная в мире программирования: некоторое уменьшение скорости выполнения программы плюс дополнительный расход памяти для каждого из объектов.
Применительно к классам-дескрипторам функции-члены должны использовать указатель на реализацию, чтобы добраться до данных самого объекта. Для каждого обращения это добавляет один уровень косвенной адресации. Кроме того, к количеству памяти, требуемому для хранения каждого объекта, вам необходимо добавить размер указателя. И наконец, указатель на реализацию должен быть инициализирован (в конструкторе класса-дескриптора), чтобы он указывал на динамически размещаемый объект реализации; следовательно, вы навлекаете на себя еще и «накладные расходы», сопровождающие динамическое выделение памяти и последующее ее высвобождение (см. правило 10).
Для классов-протоколов каждый функциональный вызов виртуален, поэтому всякий раз при вызове функции вы платите за косвенный переход (см. правило 14). Кроме того, классы, производные от класса-протокола, должны содержать указатель на таблицу виртуальных функций (и снова см. правило 14). Этот указатель может увеличить количество памяти, необходимое для храпения объекта, в зависимости от того, является ли класс-протокол единственным источником виртуальных функций объекта.
Наконец, ни классы-дескрипторы, ни классы-протоколы не могут извлечь выгоду из использования встраиваемых функций. Для практического применения встраиваемых функций требуется доступ к деталям реализации, а именно его классы-дескрипторы и классы-протоколы призваны в первую очередь ограничить.
Однако было бы серьезной ошибкой отказываться от классов-дескрипторов и классов-протоколов просто потому, что их использование связано с «дополнительными расходами». То же самое можно сказать и о виртуальных функциях, но вы ведь не отказываетесь от их применения. (В противном случае вы читаете не ту книгу.) Рассмотрите возможность использования предлагаемых приемов в процессе эволюции ваших программ. Применяйте классы-дескрипторы и классы-протоколы в процессе разработки для того, чтобы уменьшить влияние изменений в реализации на пользователей. Если вы можете показать, что различие в скорости и/или размере настолько существенно, что во имя повышения эффективности оно оправдывает увеличение зависимости между классами, то на конечной стадии реализации заменяйте классы-дескрипторы и классы-протоколы конкретными классами. Надеюсь, однажды появятся средства, позволяющие выполнять этот тип преобразования автоматически.
Умелое использование классов-дескрипторов, классов-протоколов и конкретных классов позволит вам разрабатывать эффективно выполняемое и легко модифицируемое программное обеспечение, но при этом появляется новый серьезный недостаток: вы лишаете себя перекуров на время перекомпиляции ваших программ.
f
Глава 6. Наследование
и объектно-ориентированное
проектирование
Многие полагают, что наследование - это основа объектно-ориентированного программирования. Действительно ли это так - вопрос спорный, но количество правил в других разделах данной книги должно убедить вас, что для эффективного программирования на С++ в вашем распоряжении имеется гораздо больше средств, чем просто определение того, какие классы от каких наследуют.
Тем не менее проектирование и реализация иерархии классов не имеет аналогии в мире С. Несомненно, именно в сфере наследования и объектно-ориентированного программирования вы с наибольшей вероятностью можете столкнуться с необходимостью переосмысления своего подхода к разработке программного обеспечения. Более того, С++ предоставляет широкий набор объектно-ориентированных «строительных блоков», включая открытые, защищенные и закрытые базовые классы, виртуальные и невиртуальные базовые классы, виртуальные и невиртуальные функции-члены. Все эти возможности взаимодействуют не только одна с другой, но также и с другими компонентами языка. В результате, пытаясь понять, что означает каждый из этих инструментов, когда он может быть использован и как взаимодействует с теми аспектами С++, которые не являются объектно-ориентированными, вы можете столкнуться с рядом трудностей.
Ситуация еще больше осложняется ввиду того обстоятельства, что различные средства языка на первый взгляд служат практически одинаковым целям. Приведем некоторые примеры:
Предыдущая << 1 .. 58 59 60 61 62 63 < 64 > 65 66 67 68 69 70 .. 105 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100