
- •«Объектно-ориентированный анализ и проектирование»
- •1. Принципы ооп. Классы.
- •Описание классов.
- •Объекты класса.
- •Конструкторы
- •Конструктор копирования
- •Статические элементы класса
- •Дружественные функции и классы
- •Деструкторы
- •Перегрузка операций
- •Перегрузка унарных операций
- •Перегрузка бинарных операций
- •Перегрузка операции присваивания
- •Рекомендации по составу классов
- •2. Наследование
- •Ключи доступа
- •Простое наследование
- •Пример замещения функций (практикум)
- •Виртуальные методы
- •Множественное наследование
- •3. Отношения между классами. Диаграммы класссов на языке uml.
- •4. Шаблоны классов.
- •4.1. Определения шаблонов классов Queue и QueueItem
- •4.2. Конкретизация шаблона класса
- •4.3. Аргументы шаблона для параметров-констант
- •4.4. Функции-члены шаблонов классов
- •5. Обработка исключительных ситуаций
- •5.1. Общий механизм обработки исключений.
- •5.2 . Синтаксис исключений
- •5.3. Перехват исключений
- •5.4. Исключения в конструкторах и деструкторах
- •Vector(int n) // Конструктор
- •5.5. Список исключений функции.
- •6. Строки
- •Преобразование строк
- •7. Контейнерные классы
- •7.1. Векторы.
- •7.2. Двухсторонние очереди (deque).
- •7.3. Списки (List).
- •7.4. Стеки
- •7.5. Очереди (queue)
- •7.6. Очередь с приоритетами(priority_queue)
- •8. Ассоциативные контейнеры
- •8.1. Словари (map)
- •8.2. Словари с дубликатами (multimap)
- •8.3. Множества (set)
- •8.4. Множества с дубликатами (multiset)
- •8.5. Битовые множества (bitset)
Перегрузка операций
Нельзя перегружать:
?: :: # ## sizeof
Перегрузка операций (функции-операции):
сохраняются количество аргументов, приоритеты, правила ассоциации;
нельзя использовать для стандартных типов;
не могут иметь параметров по умолчанию;
не наследуются (за исключением =);
не могут быть static ;
может определяться как
метод класса (количество параметров на 1 меньше, первым операндом является объект, вызвавший операцию);
дружественная функция класса;
обычная функция.
Синтаксис:
<тип> operator <знак операции> (<список параметров>) {тело функции}
Перегружаться операция может
1) как метод класса:
class Point{
double x, y;
public:
Point operator +(Point&);
…
};
Point::Point operator +(Point& p)
{return Point(x + p.x, y + p.y};
}
2) как внешняя функция:
class Point{
double x, y;
public:
friend Point operator +(Point&, Point& );
…
};
Point operator +(Point& p1, Point& p2) //т.к. функция дружественная,
//:: - не нужно
{return Point(p1.x + p2.x, p1.y + p2.y};
}
…
Point p1(0,2), p2(-3,5);
Point p3 = p1 + p2; // p1.operator +(p2), operator +(p1,p2)
…
Если первый операнд имеет базовый тип, то перегрузка возможна лишь в виде внешней функции.
Перегрузка унарных операций
class monstr{
…
public:
monstr& operator++(){ ++health; return *this;}
};
…
monstr Vasia;
cout << (++Vasia).get.health();
class monstr{
…
friend monstr& operator++(monstr &M);
};
…
monstr& operator++(monstr &M){++M.health; return M;}
Если функция недружественная, д.б. доступно изменяемое поле.
class monstr{
…
Void change_health(int he) {health=he;}
};
…
monstr& operator++(monstr &M){
int h = M.get_health();
h++;
M.change_health(h);
return M;}
Операции постфиксные должны иметь первый параметр типа int, чтобы отличить их от префиксной формы:
class monstr{
…
monstr operator ++(int){
monstr M = *this;
health++;
return M;}
};
…
monstr Vasia;
cout << (Vasia++).get.health();
// распечатывается первоначальное здоровье (сохраненное в M), а в
//Vasia здоровье увеличивается на 1
class Point{
double x, y;
public:
…
// префиксный метод
Point& operator++()
{x++;
y++;
return *this;
}
};
При возвращении значения по ссылке предотвращается вызов конструктора копирования (для создания возвращаемого значения и последующего вызова деструктора). Поэтому префиксная запись эффективнее постфиксной.
// постфиксный метод
Point operator ++(int)
{Point old = *this;
x++;
y++;
return old;
}
…
};
Ссылка в этом случае не подходит, так как необходимо вернуть первоначальное состояние объекта (сохраненное в old).
Перегрузка бинарных операций
class monstr{
…
public:
bool operator >(const monstr &M)
{if( health > M.health)
return true;
return false;
}
};
Если перегруженная операция определяется вне класса, она имеет 2 параметра типа класса.
class monstr{
…
};
bool operator >(const monstr &M1, const monstr &M2)
{if(M1.get_health() > M2.get_health())
return true;
return false;}
friend monstr& operator ++(monstr &M){++M.health; return M;}
…