Бьерн Страуструп. Язык программирования С++. Специальное издание (2011) (1004033), страница 106
Текст из файла (страница 106)
Если бы в классе Етр(оуее была объявлена двухаргументная версия функции орега(ог ([е1е(е [] (), то она бы вызывалась со вторым аргументом, равным е»а[деву (Етр(оуее) + (1е1(а. 15.б.2. «Виртуальные конструкторы» После знакомства с виртуальными деструкторами возникает очевидный вопрос: «Может ли конструктор быть виртуальным?», Краткий ответ — нет; чуть менее краткий ответ такой; «Нет, но обеспечить искомый эффект возможно», Глава ) 5. Иерархии классов 512 с1аее Ехрг ( риЫ(с: Ехрг (); Ехрг(соим Ехрга); //уиолчател»ный конструктор гУ копирующий конструктор г/ггиа1 Ехрг* пет ехрг() сопи (ге(ига пот Ехрг(); ) г/ггиа1 Ехрг* с(опе() сапы (ге(игл иет Ехрг (*1Ые) г ) /У...
Поскольку функции вроде пеп ехрг() и с1оие() являются виртуальными и они (косвенно) конструируют объекты, их часто называют «виртуальными конструкторами» (шутка английского языка). Каждая из этих функций просто вызывает конструктор для создания необходимого объекта. Производный класс может заместить функции пеи ехрг () и/или с1оие (), чтобы они возвращали объекты производного класса: с)ам Сопи: риьдс Ехрг ( риЫгс: Соиа() 1 Сои«((сопке Сопйа); Сопи* пет ехрг() сапе( (ге(игп иев Сопи'(); ) Сопгг* с1опе() сопи( (ге1ига пет Сопи'(*1ЬЬ) /) У... Это означает, что получив указатель типа Ехрг* на объект данной иерархии, можно создать объект «точно такого же типа».
Например: го(а иеег (Ехрг* р) ( Ехрг" р2 = р->лет ехрг (); /У ... ) Указатель, который здесь присваивается указателю р2, имеет правильный„но неизвестный тип. Для инициализации (создания) объекта конструктор должен знать его точный тип. Отсюда следует, что конструктор не может быть виртуальным. Более того, конструктор вообще не является обычной функцией. В частности, он взаимодействует со средствами управления памятью не так, как это делают обычные функции.
Следовательно, вы не можете располагать указателем на конструктор. Оба указанных ограничения можно обойти, определив функцию, которая вызывает конструктор и возвращает объект. Это полезная возможность, поскольку часто возникает необходимость в создании объекта, точный тип которого неизвестен. Класс Ьа1 Ьох гпайег (Э)2.4.4) служит примером класса, специально спроектированного для решения этой задачи.
Теперь же я представлю иную вариацию данной идеи, когда объекты класса могут предоставлять пользователю клоны (копии) самих себя или полностью новые объекты своего собственного типа. Рассмотрим следующий код: 15 7 Советы 513 Возвраты функций Солй::леп ехрг() и СопВ::с!еле() имеют тип Солй*, а не Ехрг*. Это позволяет клонировать СопЫбез потери информации о типе.
Например; го(й ивег2 (Свай* рс, Ехрг* ре) ( Соп4* р2 = рс->с(опе ( ); Соп4* рЗ = ре->с!опе (); р еггог ~у... ) Тип замешаюшей функции должен быть в точности таким же, как у замешаемой виртуальной функции, за исключением небольшого послабления по отношению к типу возвращаемого значения.
Например, если у исходной функции возврат имел тип В*, то возврат у замешаюшей функции может быть Р*, где В является открытым базовым классом для Р. Аналогично, вместо Ва, тип возврата может быть ослаблен до Ри. Заметьте, что аналогичные правила ослабления для типов аргументов привели бы к нарушению зашиты типов (см. 815.8[12)). 15.7. Советы 1. Используйте обычное множественное наследование для того, чтобы выразить обьединение свойств; 815.2, 815.2.5. 2. Используйте множественное наследования для отделения деталей реализации от интерфейса; 815.2.5. 3.
Используйте виртуальные базовые классы там, где требуется выразить обшность некоторой части (но не всех) классов иерархии; 8!5.2.5. 4. Избегайте явных приведений типов; 815.4.5. 5. Используйте Вулаплс сам там, где навигация по иерархии классов неизбежна; 815.4.1. 6. Предпочитайте Вулапис сам операции гуреЫ; 815.4.4. 7. Предпочитайте доступ рг(гаге доступу ргогесгей; 815.3.1.1. 8. не объявляйте поля данных защищенными (ргогесгеа); 815.3.1.1.
9. Если класс определяет функцию орегагогве(еге(), он должен иметь виртуальный деструктор; 8!5.6. 10. Не вызывайте виртуальные функции в процессе создания или уничтожения объекта; 815.4.3. 11. Умеренно используйте явную квалификацию для разрешения перегрузки имен членов класса и применяйте ее в основном в замегцаюших функциях; $15.2.1. Глава 1,5.
Иерархии классов 514 15.8. УПРажНЕНИЯ 1. 2. 3. 4. 5. б. 8. 18. 11. 12. (*1) Напишите шаблон ргг сааб который работает как купание сачг, только он вместо возврата нуля генерирует исключение ЬаЫ сам. (*2) Напишите программу, которая иллюстрирует влияние последовательно- сти вызова конструкторов на состояние объекта (с точки зрения йТТ1). Ана- логичным образом проиллюстрируйте процесс уничтожения объекта. (*3.5) Реализуйте версию настольной игры йечегя/Огпе!1о.
Каждый игрок мо- жет быть либо человеком, либо компьютером. Сфокусируйтесь на коррект- ной работе программы, а затем доведите качество игры компьютера до такого уровня, чтобы с ним было интересно играть. (*3) Улучшите пользовательский интерфейс игры из З15.8[3[. (*3) Определите класс графических объектов с достаточным набором операций, чтобы он мог служить в качестве базового класса для графической библиотеки (подсмотрите необходимый набор операций в какой-либо коммерческой гра- фической библиотеке). Определите класс для работы с базами данных, который служил бы базовым классом для библиотеки типов, хранящихся как последова- тельность полей в базе данных (подсмотрите необходимый набор операций в какой-либо коммерческой системе управления базами данных). Определите графические обьекты базы данных, используя подходы со множественным на- следованием и без него (сравните преимущества каждого из подходов).
("2) Напишите версию функции с1опе () из В15.6.2, которая помешала бы клони- рованные объекты в область памяти типа Агепа (см. В10.4.11), переданную в каче- стве аргумента. Реализуйте простой конкретный класс для работы с фиксирован- ными областями памяти, как производный от абстрактного класса Агапа. (*2) Не заглядывая в книгу, напишите как можно больше ключевых слов язы- ка С++. (*2) Напишите удовлетворяющую стандартам программу на С++, содержа- щую последовательность из по крайней мере десяти разных ключевых слов, не разделенных идентификаторами, знаками операций, пунктуации и т.д.
("2.5) Изобразите возможное распределение памяти для класса Яасао из й15.2.3.1. Объясните, как можно реализовать вызов виртуальной функции. (*2) Изобразите возможное распределение памяти для класса Яасао из 515.2.4. Объясните, как можно реализовать вызов виртуальной функции. (*3) Рассмотрите вопрос о том, как можно реализовать операцию аупа- ппс сам. Определите и реализуйте шаблон асахг, который ведет себя как ау- патк сахг, но использует лишь данные и функции, определенные вами.
Проверьте, что вы можете добавлять в систему новые классы, не изменяя оп- ределения Ысазг и других ранее написанных классов. (*2) Предположим, что правила проверки типов ши аргументов ослаблены аналогично правилам для типов возвращаемых значений с тем, чтобы можно было заместить функцию, имеющую аргумент типа Вазе*, на функцию с ар- гументом Рек(чего*. Напишите программу, которая может испортить обьект типа РеичеН без использования приведения типов. Опишите безопасное ос- лабление правил для типов аргументов замещаемых функций. Часть 111 Стандартная библиотека Здесь описывается стандартная библиотека языка С++.
Представлены архитектура библиотеки и ключевые методики ее реализации с целью объяснить, как использовать библиотеку эффективным образом. Также на ее примере демонстрируются общие архитектурные идеи и методики программирования. Показывается, как можно расширить библиотеку в соответствии с заложенными для этого возможностями. Главы 16.
Организация библиотеки и контейнеры 17. Стандартные контейнеры 18. Алгоритмы и классы функциональных объектов 19. Итераторы и аллокаторы 20. Строки 21. Потоки 22. Классы для математических вычислений Организация библиотеки и контейнеры Это было ново. Это было необыкновенно. Это было просто. Это должно было сработать! — Г. Нельсон Критерии проектирования стандартной библиотеки — организация библиотеки — стандартные заголовочные файлы — языковая поддержка — проектирование контейнеров — итераторы — базовые контейнеры — ЯТ1 -контейнеры— вектор (гесгог) — итераторы — доступ к элементам — конструкторы — модификаторы — операции со списками — размер и емкость — весгог<ЬооМ вЂ” советы— упражнения. 16.1.