Автор работы: Пользователь скрыл имя, 22 Декабря 2012 в 03:04, реферат
Объектно-ориентированный подход к проектированию программных систем является элементом так называемых наукоемких технологий проектирования программ. Использование этого подхода дает возможность на порядок по сравнению с обычным директивным программированием сократить трудоемкость отладки программ и внесения изменений в программу при ее последующем развитии. Платой за это является наукоемкость проектирования, т.е. уделение весьма большой части времени на детальную проработку предметной области программы, составление структуры данных и их взаимосвязи, а также проектирование программной архитектуры.
Введение………………………………………………………………………2
Механизм перегрузки………………………………………………………...3
Варианты и проблемы………………………………………………………..4
Перегрузка и полиморфные переменные…………………………………...8
Функциональная форма операторов…………………………………….....10
Перегрузка унарных операторов…………………………………………...17
Бинарные операторы. …………………………………………………….....20
Возвращаемые значения. …………………………………………………...21
Особые операторы…………………………………………………………...23
Рекомендации к форме определения операторов………………………….25
Заключение…………………………………………………………………...26
Литература……………………………………………………………………27
Если аргумент не изменяется оператором, в случае, например унарного плюса, его нужно передавать как ссылку на константу. Вообще, это справедливо для почти всех арифметических операторов (сложение, вычитание, умножение...)
Тип возвращаемого значения зависит от сути оператора. Если оператор должен возвращать новое значение, то необходимо создавать новый объект (как в случае бинарного плюса). Если вы хотите запретить изменение объекта как l-value, то нужно возвращать его константным.
Для операторов присваивания необходимо возвращать ссылку на измененный элемент. Также, если вы хотите использовать оператор присваивания в конструкциях вида (x=y).f(), где функция f() вызывается для для переменной x, после присваивания ей y, то не возвращайте ссылку на константу, возвращайте просто ссылку.
Логические операторы
должны возвращать в худшем случае
int, а в лучшем bool.
Оптимизация :
При создании новых объектов и возвращении их из функции следует использовать запись как для вышеописанного примера оператора бинарного плюса.
return Integer(left.value + right.value);
Честно говоря, не знаю, какая ситуация актуальна для C++11, все рассуждения далее справедливы для C++98. На первый взгляд, это похоже на синтаксис создания временного объекта, то есть как будто бы нет разницы между кодом выше и этим:
Integer temp(left.value + right.value);
return temp;
Но на самом деле, в
этом случае произойдет вызов конструктора
в первой строке, далее вызов конструктора
копирования, который скопирует
объект, а далее, при раскрутке
стека вызовется деструктор. При
использовании первой записи компилятор
изначально создаёт объект в памяти,
в которую нужно его
9.Особые операторы.
В C++ есть операторы, обладающие специфическим синтаксисом и способом перегрузки. Например оператор индексирования []. Он всегда определяется как член класса и, так как подразумевается поведение индексируемого объекта как массива, то ему следует возвращать ссылку.
В число «особых» операторов входит также оператор запятая. Он вызывается для объектов, рядом с которыми поставлена запятая (но он не вызывается в списках аргументов функций). Придумать осмысленный пример использования этого оператора не так-то просто. Хабраюзер AxisPod в комментариях к предыдущей статье о перегрузке рассказал об одном.
Перегрузка разыменования указателя этих операторов может быть оправдана для классов умных указателей. Этот оператор обязательно определяется как функция класса, причём на него накладываются некоторые ограничения: он должен возвращать либо объект (или ссылку), либо указатель, позволяющий обратиться к объекту.
Оператор присваивания обязательно определяется в виде функции класса, потому что он неразрывно связан с объектом, находящимся слева от "=". Определение оператора присваивания в глобальном виде сделало бы возможным переопределение стандартного поведения оператора "=". Пример:
class Integer
{
private:
int value;
public:
Integer(int i): value(i)
{}
Integer& operator=(const Integer& right) {
//проверка на самоприсваивание
if (this == &right) {
return *this;
}
value = right.value;
return *this;
}
};
Как можно заметить, в начале функции производится проверка на самоприсваивание. Вообще, в данном случае самоприсваивание безвредно, но ситуация не всегда такая простая. Например, если объект большой, можно потратить много времени на ненужное копирование, или при работе с указателями.
Некоторые операторы в C++ не перегружаются в принципе. По всей видимости, это сделано из соображений безопасности.
Оператор выбора члена класса ".".
Оператор разыменования указателя на член класса ".*"
В С++ отсутствует оператор возведения в степень (как в Fortran) "**".
Запрещено определять свои операторы (возможны проблемы с определением приоритетов).
Нельзя изменять приоритеты операторов
10.Рекомендации к форме определения операторов.
Как мы уже выяснили, существует два способа операторов — в виде функции класса и в виде дружественной глобальной функции. Роб Мюррей, в своей книге C++ Strategies and Tactics определил следующие рекомендации по выбору формы оператора:
оператор |
Рекомендуемая форма |
все унарные операторы |
Челен класса |
= () [] -> ->* |
Обязательно член класса |
+= -= /= *= ^= &= |= %= >>= <<= |
Челен класса |
Остальные бинарные операторы |
Не челен класса |
Почему так? Во-первых, на некоторые операторы изначально наложено ограничение. Вообще, если семантически нет разницы как определять оператор, то лучше его оформить в виде функции класса, чтобы подчеркнуть связь, плюс помимо этого функция будет подставляемой (inline). К тому же, иногда может возникнуть потребность в том, чтобы представить левосторонний операнд объектом другого класса. Наверное, самый яркий пример — переопределение << и >> для потоков ввода/вывода.
11.Заключение.
Перегрузка операторов —
это возможность назначать
Чтобы перегрузить оператор, вы должны определить класс, которому оператор будет назначен.
Когда вы перегружаете оператор, перегрузка действует только для класса, в котором он определяется. Если программа использует оператор с неклассовыми переменными (например, переменными типа int или float), используется стандартное определение оператора.Чтобы перегрузить оператор класса, используйте ключевое слово C++ operator для определения метода класса, который C++ вызывает каждый раз, когда переменная класса использует оператор.
Объектно-ориентированные
языки программирования пользуются
в последнее время большой
популярностью среди
12.Литература.