Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
информатика.doc
Скачиваний:
60
Добавлен:
09.02.2015
Размер:
450.05 Кб
Скачать

Запреты на перегрузку операций

Большая часть операций С++ может быть перегружена. Эти операции приведены ниже.

Операции, которые могут быть перегружены

+

-

*

/

%

^

&

|

~

!

=

<

>

+=

-=

*=

/=

%=

^=

&=

|=

<<

>>

>>=

<<=

= =

!=

<=

>=

&&

||

++

--

->*

,

->

[]

( )

new

delete

Теперь приведем операции, которые не могут перегружаться.

Операции, которые не могут быть перегружены

.

.*

::

?:

sizeof

Приоритет операций не может быть изменен посредством перегрузки. Это может привести к неудобным ситуациям, когда операция перегружается так, что ее фиксированный приоритет плохо соответствует смыслу выполняемых действий. Тем не менее, остается возможность использовать скобки для опре­деления порядка оценки перегруженных операций в выражении.

Ассоциативность операций также не может быть изменена посредством перегрузки. Для перегрузки операций нельзя использовать аргументы по умолчанию.

Отсутствует возможность изменить число операндов, которое подразуме­вает операция. Одноместная операция остается одноместной и при перегрузке, а двухместная остается двухместной. Единственная трехместная операция С++, условная (?:), не может быть перегружена. Каждая из операций &, *, + и - имеет одноместную и двухместную формы, которые могут перегружаться раздельно.

Нельзя создавать новые операции; только существующие операции могут быть перегружены. Это запрещает программисту пользоваться такими попу­лярными нотациями, как операция **, означающая в языке Basic возведение в степень.

При перегрузке ( ), [ ], -> или = перегружающая операцию функция дол­жна объявляться как функция-элемент. Для других операций перегружаю­щие функции могут быть друзьями.

Перегрузка операции присваивания и операции суммирования с целью разрешить такие операции, как

object2 = object2 + object1;

не означает, что автоматически будет перегружена операция +=, чтобы выпол­нялся такой оператор, как

object2 += object1;

Однако такое поведение может быть достигнуто посредством явной пере­грузки операции += для этого класса.

2 Базовые и производные классы.

Наследование представляет собой механизм повторного использования программного обеспечения, в соответствии с кото­рым новые классы создаются на основе существующих. Эти классы наследуют свойства и поведение базовых классов и приобретают дополнительно новые, необходимые для новых классов, качества. Возможность повторного использо­вания программного обеспечения сберегает время, затраченное на его разработку, способствует повторному использованию апробированного и отлажен­ного высококачественного программного обеспечения и уменьшает число эксплутационных проблем, когда система начинает функционировать. Это сулит богатые возможности. Полиморфизм позволяет нам писать программы в об­щем виде для обработки большого разнообразия существующих и определяе­мых в дальнейшем логически связанных классов. Наследование и полимор­физм представляют собой эффективные методики для разработки сложных программных систем.

При создании нового класса вместо того, чтобы писать совершенно новые элементы данных и функции-элементы, программист может просто указать, что новый класс должен наследовать элементы ранее определенного базового класса. Этот новый класс называется производным классом. Каждый произ­водный класс, в свою очередь, может быть базовым для каких-то будущих производных классов. При простом наследовании производный класс получа­ется на основе только одного базового класса. При сложном наследовании про­изводный класс наследует свойства от многих (возможно, логически не свя­занных) классов. Новый класс, как правило, вводит свои элементы данных и функции, поэтому производный класс, вообще говоря, «больше» исходного ба­зового класса. Новый производный класс имеет больше специфических свойств в сравнении с исходным базовым и представляет меньшую группу объ­ектов. В случае простого наследования производный класс в своей основе оста­ется по существу таким же, как базовый класс. Настоящая сила наследования определяется возможностью добавлять, замещать и уточнять наследуемые от базовых классов свойства.

Каждый объект производного класса является также объектом базового класса, из которого получен этот производный класс. Однако противополож­ное неверно - объекты базового класса не являются объектами производных классов базового объекта. Мы воспользуемся этим отношением - «объект производного класса является объектом базового класса», чтобы выполнять некоторые интересные преобразования. Например, мы можем перечислить много разных объектов, связанных отношением наследования, в связанном списке объектов базового класса. Это позволит обрабатывать разные объекты одним общим образом. Как мы в дальнейшем увидим в этой и следующей гла­вах, это является одним из важнейших методов объектно-ориентированного программирования.

Мы введем в этой лекции новое средство для управления доступом к элемен­ту - речь идет о защищенном доступе. Производные и дружественные им классы имеют право доступа к защищенным элементам базового класса; у остальных функций такого права нет.

Производный класс не может иметь доступа к закрытым элементам своего базового класса; такой доступ нарушал бы инкапсуляцию последнего. Однако производный класс может иметь доступ к открытым и защищенным элемен­там базового класса. Элементы базового класса, доступ к которым не разрешен для производного класса через отношение наследования, должны быть объяв­лены в базовом классе как закрытые. Производный класс может иметь доступ к закрытым элементам базового класса только через специальные функции доступа, предоставляемые открытым интерфейсом базового класса.

Одна проблема с наследованием заключается в том, что производный класс может наследовать открытые функции-элементы, которые не нужно или не следовало бы иметь в «потомстве» явно. Если какой-нибудь элемент ба­зового класса не подходит для производного класса, этот элемент может быть переопределен в самом производном классе с соответствующей реализацией.

Часто объект одного класса «является» также и объектом другого класса. Прямоугольник - rectangle, конечно же, является четырехугольником - quadrilateral (как являются и квадрат, и параллелограмм, и трапеция). Таким образом, о классе Rectangle можно сказать, что он наследует классу Quadrila­teral. В этом смысле класс Quadrilateral называется базовым, а класс Rectan­gle называется производным. Прямоугольник является специальным типом четырехугольника, но нельзя исходя из этого утверждать, что четырехуголь­ник является прямоугольником.

Защищенные элементы.

Все функции программы имеют доступ к открытым элементам базового класса. Доступ к закрытым элементам базового класса имеют только элемен­ты-функции самого класса и его «друзья».

Защищенный доступ представляет собой промежуточный уровень защиты между закрытым и открытым доступом. Защищенные элементы базового класса могут быть доступны только для элементов и друзей самого класса и для элементов и друзей производных классов.

Элементы производного класса могут вызывать открытые и защищенные элементы базового класса просто по имени элемента. При этом не обязательно использовать операцию разрешения области действия - по умолчанию имеет­ся в виду текущий объект.

Сложное наследование.

До сих пор мы обсуждали механизм простого наследования, в котором каждый класс выводится только из одного базового класса. Однако класс может быть получен из нескольких базовых классов; такой механизм образования класса называется сложным наследованием. Сложное наследова­ние означает, что производный класс наследует элементы нескольких базовых классов. Этот мощный механизм дает интересные формы повторного исполь­зования программного обеспечения, но вместе с тем может порождать ряд проблем, связанных с неоднозначностью.

Абстрактные базовые классы и конкретные классы

Когда мы говорим о классе как о типе, мы подразумеваем, что будут созда­ваться объекты этого типа. Однако во многих случаях бывает полезно опреде­лять классы, объекты которых не будут создаваться. Такие классы называют­ся абстрактными классами. Поскольку они используются в наследовании в качестве базовых классов, мы будем называть их абстрактными базовыми классами. Объекты абстрактного базового класса создавать нельзя.

Единственная цель определения абстрактного класса состоит в том, чтобы предусмотреть обобщенныйбазовый класс, на основе которого строится иерар­хия наследования. Классы, для которых могут создаваться объекты, называ­ются конкретными классами.Например, мы могли бы определить абстрактный базовый класс TwoDimensionalObject и произвести от него классы типа Square, Circle, Triangle