ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 19.04.2024
Просмотров: 184
Скачиваний: 0
СОДЕРЖАНИЕ
1 Основные принципы перегрузки операций
Запреты на перегрузку операций
Динамическое распределение памяти
4. Классы программных продуктов
1) Составление технического задания на программирование
2) Составление технического проекта
3) Создание рабочей документации (рабочего проекта)
2) Графический интерфейс пользователя
9. Сети эвм и протоколы передачи информации:
1 Основные принципы перегрузки операций
Ранее мы познакомились с классами С++ и с абстрактными типами данных (ADT). Операции с объектами класса (т.е. представителями ADT) осуществлялись посредством посылки сообщений объектам (в форме вызова функций-элементов). Нотация такого вызова функции становится громоздкой для определенных категорий классов, в особенности для математических. Чтобы оперировать с объектами таких классов, было бы удобно использовать широкий набор встроенных операций С++. В этой лекции мы покажем, как разрешить операциям С++ работать с объектами класса. Этот процесс называется перегрузкой операций и является прямым и естественным путем к расширению С++ за счет этих новых возможностей.
Операция << в С++ может иметь различный смысл и используется в качестве операции передачи в поток и операции сдвига влево. Это пример перегруженной операции. Операция >> также перегружена, поскольку она используется как операция извлечения из потока и как операция правого сдвига. Обе эти операции перегружаются в библиотеке классов С++. Сам по себе С++ уже перегружает операции + и -. Эти операции выполняют различные функции, которые зависят от контекста применения - в целочисленной арифметике, арифметике чисел с плавающей точкой и арифметике указателей.
В целом С++ дает программисту возможность перегружать большинство операций, так чтобы они были чувствительны к контексту, в котором применяются. Компилятор генерирует соответствующий программный код, исходя из способа применения данной операции. Некоторые операции перегружаются достаточно часто, особенно операции присваивания и различные арифметические операции, такие как + и -. Программист также может использовать операции с типами, определенными пользователем. Несмотря на то, что С++ не позволяет создавать новые операции, он позволяет перегружать существующие операции и, когда они применяются к объектам класса, операции приобретают смысл, соответствующий новым типам. Это очень сильная сторона С++.
Несмотря на то, что перегрузка операций может восприниматься как некая экзотическая возможность, большинство программистов неявно используют перегруженные операции. Например, операция плюс (+) работает существенно различным образом с целыми, числами с плавающей точкой и числами с двойной точностью. Но плюс, тем не менее, прекрасно работает с переменными типа int, float и double, а также с числами других встроенных типов, поскольку операция плюс (+) перегружена уже в самом языке С++.
Операции перегружаются посредством написания обычного определения функции (с заголовком и телом) за исключением того, что именем функции становится ключевое слово operator с последующим символом перегружаемой операции. Например, имя функции operator могло бы использоваться для перегрузки аддитивной операции.
Чтобы использовать операцию с объектами класса, эта операция должна быть перегружена, но здесь есть два исключения. Операция присваивания (=) может использоваться с любым классом без перегрузки. Поведение по умолчанию операции присваивания (в тех случаях, когда она не перегружена) обеспечивается поэлементным копированием элементов данных класса. Такая поэлементная копия, создаваемая по умолчанию, представляет опасность для классов, элементы которых ссылаются на динамически выделяемые области памяти; для таких классов мы, как правило, будем перегружать операцию присваивания. Операция адреса (&) также может использоваться с объектами любого класса без перегрузки; эта операция просто возвращает адрес объекта в памяти. Операция адреса может быть также перегружена.
Перегрузка в наибольшей степени подходит для математических классов. Они часто требуют перегрузки большого перечня операций, чтобы сохранялась согласованность со способом обработки математических объектов, которые существуют в реальной жизни.
Запреты на перегрузку операций
Большая часть операций С++ может быть перегружена. Эти операции приведены ниже.
Операции, которые могут быть перегружены |
|||||||
+ |
- |
* |
/ |
% |
^ |
& |
| |
~ |
! |
= |
< |
> |
+= |
-= |
*= |
/= |
%= |
^= |
&= |
|= |
<< |
>> |
>>= |
<<= |
= = |
!= |
<= |
>= |
&& |
|| |
++ |
-- |
->* |
, |
-> |
[] |
( ) |
new |
delete |
Теперь приведем операции, которые не могут перегружаться.
Операции, которые не могут быть перегружены |
||||
. |
.* |
:: |
?: |
sizeof |
Приоритет операций не может быть изменен посредством перегрузки. Это может привести к неудобным ситуациям, когда операция перегружается так, что ее фиксированный приоритет плохо соответствует смыслу выполняемых действий. Тем не менее, остается возможность использовать скобки для определения порядка оценки перегруженных операций в выражении.
Ассоциативность операций также не может быть изменена посредством перегрузки. Для перегрузки операций нельзя использовать аргументы по умолчанию.
Отсутствует возможность изменить число операндов, которое подразумевает операция. Одноместная операция остается одноместной и при перегрузке, а двухместная остается двухместной. Единственная трехместная операция С++, условная (?:), не может быть перегружена. Каждая из операций &, *, + и - имеет одноместную и двухместную формы, которые могут перегружаться раздельно.
Нельзя создавать новые операции; только существующие операции могут быть перегружены. Это запрещает программисту пользоваться такими популярными нотациями, как операция **, означающая в языке Basic возведение в степень.
При перегрузке ( ), [ ], -> или = перегружающая операцию функция должна объявляться как функция-элемент. Для других операций перегружающие функции могут быть друзьями.
Перегрузка операции присваивания и операции суммирования с целью разрешить такие операции, как
object2 = object2 + object1;
не означает, что автоматически будет перегружена операция +=, чтобы выполнялся такой оператор, как
object2 += object1;
Однако такое поведение может быть достигнуто посредством явной перегрузки операции += для этого класса.
2 Базовые и производные классы.
Наследование представляет собой механизм повторного использования программного обеспечения, в соответствии с которым новые классы создаются на основе существующих. Эти классы наследуют свойства и поведение базовых классов и приобретают дополнительно новые, необходимые для новых классов, качества. Возможность повторного использования программного обеспечения сберегает время, затраченное на его разработку, способствует повторному использованию апробированного и отлаженного высококачественного программного обеспечения и уменьшает число эксплутационных проблем, когда система начинает функционировать. Это сулит богатые возможности. Полиморфизм позволяет нам писать программы в общем виде для обработки большого разнообразия существующих и определяемых в дальнейшем логически связанных классов. Наследование и полиморфизм представляют собой эффективные методики для разработки сложных программных систем.
При создании нового класса вместо того, чтобы писать совершенно новые элементы данных и функции-элементы, программист может просто указать, что новый класс должен наследовать элементы ранее определенного базового класса. Этот новый класс называется производным классом. Каждый производный класс, в свою очередь, может быть базовым для каких-то будущих производных классов. При простом наследовании производный класс получается на основе только одного базового класса. При сложном наследовании производный класс наследует свойства от многих (возможно, логически не связанных) классов. Новый класс, как правило, вводит свои элементы данных и функции, поэтому производный класс, вообще говоря, «больше» исходного базового класса. Новый производный класс имеет больше специфических свойств в сравнении с исходным базовым и представляет меньшую группу объектов. В случае простого наследования производный класс в своей основе остается по существу таким же, как базовый класс. Настоящая сила наследования определяется возможностью добавлять, замещать и уточнять наследуемые от базовых классов свойства.
Каждый объект производного класса является также объектом базового класса, из которого получен этот производный класс. Однако противоположное неверно - объекты базового класса не являются объектами производных классов базового объекта. Мы воспользуемся этим отношением - «объект производного класса является объектом базового класса», чтобы выполнять некоторые интересные преобразования. Например, мы можем перечислить много разных объектов, связанных отношением наследования, в связанном списке объектов базового класса. Это позволит обрабатывать разные объекты одним общим образом. Как мы в дальнейшем увидим в этой и следующей главах, это является одним из важнейших методов объектно-ориентированного программирования.
Мы введем в этой лекции новое средство для управления доступом к элементу - речь идет о защищенном доступе. Производные и дружественные им классы имеют право доступа к защищенным элементам базового класса; у остальных функций такого права нет.
Производный класс не может иметь доступа к закрытым элементам своего базового класса; такой доступ нарушал бы инкапсуляцию последнего. Однако производный класс может иметь доступ к открытым и защищенным элементам базового класса. Элементы базового класса, доступ к которым не разрешен для производного класса через отношение наследования, должны быть объявлены в базовом классе как закрытые. Производный класс может иметь доступ к закрытым элементам базового класса только через специальные функции доступа, предоставляемые открытым интерфейсом базового класса.
Одна проблема с наследованием заключается в том, что производный класс может наследовать открытые функции-элементы, которые не нужно или не следовало бы иметь в «потомстве» явно. Если какой-нибудь элемент базового класса не подходит для производного класса, этот элемент может быть переопределен в самом производном классе с соответствующей реализацией.
Часто объект одного класса «является» также и объектом другого класса. Прямоугольник - rectangle, конечно же, является четырехугольником - quadrilateral (как являются и квадрат, и параллелограмм, и трапеция). Таким образом, о классе Rectangle можно сказать, что он наследует классу Quadrilateral. В этом смысле класс Quadrilateral называется базовым, а класс Rectangle называется производным. Прямоугольник является специальным типом четырехугольника, но нельзя исходя из этого утверждать, что четырехугольник является прямоугольником.