|
Программирование >> Полиморфизм без виртуальных функций в с++
типов С++. Закончив работу над версией 1.0, я нашел выход и включил указатель на функцию-член в версию 1.2. Оказалось, что для сред, в которых функции обратного вызова использовались как основной механизм коммуникации, решение и.меет первостепенное значение. Тер.мин указатель на член несколько неточен, поскольку это, скорее, смешение, значение, идентифицируюшее член объекта. Однако, назови я его смешением , пользователи сделали бы ошибочный вывод, будто указатель на член - просто индекс, и могли бы решить, что к нему применимы какие-то арифметические операции. Это привело бы к еше большей путанице. Данный термин был выбран потому, что проектировал механизм в форме синтаксической параллели указателям в С. Давайте рассмотрим синтаксис функции C/C++ на примере: int f(char* р) { /* .. int {*pf)(char*) = &f; int i = (*pf)( hello ); Включая в подходящие места S: циями-членами: class S { ... int mf(char*); определяем функцию объявляем и инициализируем указатель на функцию вызываем через указатель ; И р->, Я построил прямую параллель с функ- int S: :inf (char* р) ; int (S::*pmf)(char* S* p; int i = {p->*pmf) {/*...*/} = &S: :mf , hello определяем функцию объявляем и инициализируем указатель на функцию-член вызываем через указатель и объект Семантически и синтаксически понятие указателя на функцию-член осмысленно. Мне оставалось обобщить его, включив понятие данных-членов, и найти стратегию реализации. В разделе благодарностей работы [Lippman, 1988] есть такие строки: Проектирование указателей на члены было выполнено совместно Бьерном Страуструпом и Джонотоном Шопиро. Много полезных замечаний высказал также Дуг Мокилрой. Стив Дьюхерст немало сделал для переработки механизма указателей но члены с учетом множественного наследования . Тогда я многократно повторял, что указатели на члены оказались более полезными, чем планировалось изначально. То же можно сказать о версии 2.0 в целом. Указатели на данные-члены оказались полезны и для описания размещения класса С++ в памяти таким способом, который не зависит от реализации [Hubel, 1992]. Глава 14. Приведение типов Умный человек не станет изменять мир. Дж. Б. Шоу 14.1. Крупные расширения Шаблоны (см. главу 15), исключения (см. главу 16), идентификацию типов во время исполнения (см. раздел 14.2) и пространства имен (см. главу 17) часто называют крупными расширения.ми. Они оказывают влияние иа способ организации программ, так что считать ли их расширениями или неотъемлемыми особенностями С-1-1- - это дело вкуса. Мелкие же расширения не влияют на структуру програм.мы в целом, не сказываются на проектировании. Они названы так вовсе не потому, что для их описания требуется всего несколько строк в руководстве, а для реализации - несколько строк кода в компиляторе. На са.мом деле некоторые крупные распшрения описать и реализовать проще, чем кое-какие мелкие. Конечно, не каждую возможность, и.меющуюся в языке, легко отнести к одной из этих двух категорий. Например, вложенные функции можно считать .мелким или крупным расширением в зависи.мости от того, насколько важны.м ва.м кажется их применение для выражения итераций. Любопытно, что проявленный общественностью интерес к тому или иному средству обратно пропорционален его важности. С другой стороны, именно такое реагирование понятно: гораздо проще определить свое отношение к мелкому усовершенствованию, нежели к крупно.му; не очень существенные средства, в отличие от принципиально важных, нетрудно соотнести с текущим состоянием языка. Поскольку поддержка построения библиотек и создания программного обеспечения из относительно независимых частей - главная цель С++, именно с ней и связаны крупные расширения: шаблоны, обработка исключений, идентификация типа во время исполнения и пространства имен. Первое и второе средства я с самого начала считал необходимой частью того, чем должен стать С++ (см. разделы 2.9.2 и 3.15). Идентификация типа во время исполнения рассматривалась еще в первой редакции предварительного стандарта C-i-i- (см. раздел 3.5), но была отложена в надежде, что окажется ненужной. Пространства имен - единственное крупное расщирение, которого не было в первоначальной концепции C-i-i-, оно решает проблему, к которой я безуспешно подступался в первой версии (см. раздел 3.12). 14.2. Идентификация типа во время исполнения Во многих отношениях дискуссия об идентификации типа объекта во время исполнения напоминает обсуждение множественного наследования (см. раздел 12.6). Множественное наследование считалось первым круп)1ы.м расширением изначального определения С++. Идентификация типа во время исполнения (часто ее называют RTTI - Run-Time Type Identification) - первое крупное расширение, которое заранее не предполагалось стандартизировать и которое не описано в ARM. В С++ вводилась прямая поддержка нового стиля программирования, и некоторые гюльзователи naHajni: □ объявлять, что такая поддержка не нужна; □ утверждать, что новый стиль несовершенен ( не в стиле С++р); Zi говорить, что это чересчур расточительно; J думать, что это слишко.м сложно и запутанно; □ предполагать, что новый стиль повлечет за собой массу новых расширений. Кро.ме того, RTTI pacKpnTHKOBajm, поскольку она вообше была связана с ме-ханиз.мом приведения типов в С++. Так, многим пользователям не нравится, что старые приведения тигюв можно применять, чтобы обойти контроль доступа для закрыто наследуемых базовых классов и отменить действие модификатора const. Для такой критики есть важные и серьезные основания; они обсуждаются в разделе 14.3. И снова, как и раньше, я защищал новое средство, доказывая, что для кого-то оно важно, а остальным пе мешает, что реализовать его несложно и что если не поддержать RTTI напря.мую, то пользователям придется ее эмулировать. Пришлось даже сделать экспериментальную реализацию за два утра, продемонстрировав, что RTTI, по крайней мере, на порядок проще исключений и шаблонов и на два порядка проще множественного наследования. Добавить средства идентификации типа объекта во время исполнения предложил Дмитрт1 Ленков [Lenkov, 1991]. Он основывался на опыте использования больших библиотек па С++ типа Interviews [Linton, 1987], NIH [Gorlen, 1990] и ET-t-i- [Weinand, 1988]. Исследовался также механизм досье (dossier) [Interrante, 1990]. Механизмы RTTI, которые предоставлялись разными библиотеками, были несовместимы между собой, и это стало препятствием для использования сразу нескольких библиотек. Кроме того, в каждом случае от проектировщика базовых классов требовалось многое предвидеть. Следовательно, был необходим какой-то .механизм, который поддерживался бы самим языком. Я занимался проектированием такого механизма в соавторстве с Ленковым [Stroustrup, 1992]. В июле 1991 г. на заседании в Лондоне предложение было представлено комитету ANSI/ISO, а в марте 1993 г. на заседании в Портленде его одобрили. Механизм идентификации типа во время исполнения состоит из трех частей: □ оператор dynamic cast для получения указателя на объект производного класса при натичии указателя на базовый класс этого объекта. Оператор
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |