Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
43
Добавлен:
16.04.2013
Размер:
62.98 Кб
Скачать

Ad hoc полиморфизм

Полиморфизм (polymorphism) — это способ присваивать различные значения (смыс­лы) одному и тому же сообщению. Смысл зависит от типа обрабатываемых данных. «Объектно-ориентированность» использует преимущества полиморфизма, привя­зывая поведение к типу объекта. Такие операторы, как + или « могут иметь различ­ный смысл в зависимости от типов операндов.

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

Операторы перегружаются и выбираются на основе алгоритма соответствия сиг­натуре. Перегрузка операторов придает им новые значения. Например, выражение а + b имеет различные значения, зависящие от типа переменных а и Ь. Перегрузка оператора + для определяемых пользователем типов дает возможность применять их в выражениях сложения почти таким же образом, как собственные типы. Выражение а + b может означать конкатенацию строк, сложение комплексных чисел или сло­жение целых, в зависимости от того, являются ли переменные абстрактными типами данных my_string или complex, или собственным типом int. Аналогично, благо­даря функциям преобразования возможны выражения смешанных типов. В этой гла­ве также обсуждаются дружественные функции (friend function), и почему они кри­тичны для перегрузки операторов.

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

Преобразования атд

Явное преобразование типов в выражениях необходимо, если неявное преобразование нежелательно или если без такого преобразования выражение будет недопустимым. Одна из задач ООП на C ++ состоит в интеграции определяемых пользователем АТД и встроенных типов. Для этого существует механизм, позволяющий функциям-членам обеспечивать явные преобразования.

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

my_string::my_string(const char* p);

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

my_string s;

char* logo = "Рога и Копыта Лтд.";

s = static_cast<my_string>(logo);

и преобразование

s = logo; //неявный вызов преобразования

будут работать. Обратите внимание, что такое использование требует перегрузки оператора присваивания (см. раздел 7.7, «Перегрузка операторов присваивания и индексирования», стр. 202).

Здесь показаны преобразования уже определенного типа к пользовательскому типу. Однако пользователь не может добавить конструктор во встроенный тип, такой как int или double. С другой стороны, можно определить специальную функцию преобразования внутри класса. В общем виде подобная функция-член выглядит так

operator тип() { ••••• }

Данная функция-член должна быть нестатической. Она не может иметь параметры и не имеет объявленного возвращаемого типа. Она должна возвращать выражение указанного типа.

В примере с my_string может понадобиться преобразование my_string в char*. Это можно сделать следующим образом:

В файле string7.срр

my_string::operator char*()

{

char* p = new char[len +1];

assert(p != 0);

strcpy(p, s) ;

return p;

}

Заметьте, что мы не просто возвращаем значение закрытого члена s. Делая так, мы нарушили бы целостность объектов my_string.

Соседние файлы в папке Тельминов (мб)