Стефан Дэвис - С++ для чайников .
- Название:С++ для чайников .
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс. Компьютерное издательство Диалектика
- Год:2007
- Город:Москва
- ISBN:0-7645-6852-3, 978-5-8459-0723-3
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стефан Дэвис - С++ для чайников . краткое содержание
1
empty-line
4
С++ для чайников . - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Из этого рисунка видно, что класс SleeperSofa включает Furniture , а также части классов Bed и Sofa , не содержащие Furniture . Далее находятся уникальные для класса SleeperSofa члены ( элементы в памяти не обязательно будут располагаться именно в таком порядке, но в данном обсуждении это несущественно ).
Теперь обращение к члену weight в функции fn( ) не многозначно, поскольку SleeperSofa содержит только одну копию Furniture . Наследуя этот класс виртуально, мы получили желаемую структуру наследования ( см. рис. 26.2 ).
_________________
305 стр. Глава 26. Множественное наследование
Если виртуальное наследование так хорошо решает проблему неоднозначности, почему оно не является нормой? Во-первых, потому, что виртуально наследуемый класс обрабатывается иначе, чем обычный наследуемый базовый класс, что, в частности, выражается в повышенных накладных расходах. Во-вторых, у вас может появиться желание иметь две копии базового класса ( хотя это случается весьма редко ). Вспомним наши старые упражнения со студентами и преподавателями и допустим, что TeacherAssistant ( помощник преподавателя ) является одновременно и Teacher ( преподавателем ) и Student ( студентом ), которые, в свою очередь, являются подклассами Academician . Если университет даст помощнику преподавателя два идентификатора — и студента и преподавателя, то классу TeacherAssistant понадобятся две копии класса Academician .
Рис. 26.5. Расположение класса SleeperSofa в памяти при использовании виртуального наследования
►Конструирование объектов...306
При конструировании объектов с использованием множественного наследования должен выполняться ряд правил.
20.Сначала вызываются конструкторы для каждого виртуального базового класса в порядке наследования.
21.Затем вызываются конструкторы каждого невиртуального базового класса в порядке наследования.
22.После этого вызываются конструкторы всех объектов-членов класса в том порядке, в котором эти объекты-члены объявлены в классе.
23.И наконец, вызывается конструктор самого класса.
Обратите внимание, что базовые классы конструируются в порядке наследования, а не в порядке расположения в строке конструктора.
►Отрицательные стороны множественного наследования...306
Должен признаться, что не все, кто работает с объектно-ориентированным программированием, считают механизм множественного наследования удачным. Кроме того, многие объектно-ориентированные языки вообще не поддерживают множественного наследования, реализация которого, кстати, далеко не самая простая вещь. Конечно, множественное наследование — это проблема компилятора ( вернее, того, кто пишет компилятор ). Однако оно требует больших накладных расходов по сравнению с программой с обычным наследованием, а эти накладные расходы становятся уже проблемой программиста.
_________________
306 стр. Часть 5. Полезные особенности
Не менее важно и то, что множественное наследование открывает путь к дополнительным ошибкам. Во-первых, неоднозначность, подобная описанной в предыдущем разделе, может превратиться в большую проблему. Во-вторых, при наличии множественного наследования преобразования указателя на подкласс в указатель на базовый класс иногда приводят к запутанным и непонятным изменениям этого указателя. Все эти тонкости я оставляю на совести разработчиков языка и компилятора.
Думаю, вам стоит избегать множественного наследования, пока вы в полной мере не освоите С++. Обычное наследование тоже достаточно мощный механизм. Исключением может стать библиотека Microsoft Foundation Classes ( MFC), в которой множественное наследование используется сплошь и рядом. Однако эти классы тщательно выверены профессиональными высококвалифицированными программистами.
Только не поймите меня неправильно! Я не против множественного наследования. То, что Microsoft и другие компании эффективно используют множественное наследование в своих классах, доказывает, что так можно делать. Если бы этот механизм не стоил того, они бы его не использовали. Однако это отнюдь не значит, что множественное наследование имеет смысл применять, едва познакомившись с ним.
_________________
307 стр. Глава 26. Множественное наследование
ОГЛАВЛЕНИЕ
В этой главе...
►Обобщение функции в шаблон 309
►Шаблоны классов 311
►Зачем нужны шаблоны классов 314
►Советы по использованию шаблонов 316
Стандартная библиотека С++ предоставляет программисту множество различных функций. В ней представлены математические функции, функции для работы со временем и датами, функции ввода-вывода, системные функции. Во многих программах в этой книге использованы, например, функции для работы с нуль-завершёнными строками ( эти функции объявлены в заголовочном файле strings.h ). Типы аргументов большинства функций фиксированы. Так, например, оба аргумента функции strcpy( char* , const char* ) являются указателями на нуль-завершённые строки — любые другие типы аргументов для данной функции просто лишены смысла.
Есть функции, которые могут быть применены к различным типам данных. Рассмотрим, например, функцию maximum( ) , которая возвращает больший из двух аргументов. Все объявления функции, приведённые в табл. 27.1, имеют смысл.
Таблица 27.1. Возможные варианты функции maximum( )
_________________
Имя функции — Выполняемые действия
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
maximum( int , int )— Возвращает большее из двух целых чисел
maximum( unsigned int , unsigned int )— Возвращает большее из двух беззнаковых целых чисел
maximum( double , double )— Возвращает большее из двух чисел с плавающей точкой
maximum( char , char )— Возвращает символ, находящийся далее в алфавитном порядке
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Я бы хотел реализовать функцию maximum( ) для всех четырёх случаев. Само собой, С++ может привести все эти типы к типу double , т.е. мне достаточно разработать функцию maximum ( double , double ) , которая удовлетворит все мои потребности. Так ли это? Рассмотрим следующий код.
/* Прототип функции maximum */
double maximum( double , double ) ;
/* Пользовательская функция */
void fn ( int nArg1 , int nArg2 )
{
int nLarger = ( int )maximum( ( double )nArg1 ,
( double )nArg2 ) ;
/* ... прочие действия ... */
}
_________________
308 стр. Часть 5. Полезные особенности
Читать дальшеИнтервал:
Закладка: