- •Введение в перегрузку операций
- •Операции, как функции
- •Использование перегруженных операций
- •Ограничения в перегрузке операций
- •Перегрузка операций через дружественные функции
- •Перегрузка операций через дружественные функции
- •Int main () {
- •I have 16 dollars.
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •Дружественные функции могут быть определены внутри класса
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •Перегрузка операций с операндами разных типов
- •Int m_dollars;
- •Int getDollars () {return m_dollars;}
- •Int main () {
- •Values (int min, int max) {
- •Int getMin () {return m_min;}
- •Int getMax () {return m_max;}
- •Int main () {
- •Int main () {
- •Int main () {
- •Перегрузка операций через обычные функции
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •Перегрузка операций ввода и вывода
- •Void print () {
- •Int main () {
- •Int main () {
- •Int main () {
- •Int main () {
- •Int main () {
- •Int m_numerator;
- •Int m_denominator;
- •Void reduce () {
- •Void print () {
- •Перегрузка операций через методы классов
- •Int m_dollars;
- •Int getDollars () { return m_dollars; }
- •Int main () {
- •Int m_dollars;
- •Int getDollars () {return m_dollars;}
- •Int main (){
- •Не всё может быть перегружено через дружественные функции
- •Не всё может быть перегружено через методы класса
- •Int main (){
- •Какой способ перегрузки и когда следует использовать?
- •Int m_dollars;
- •Int getDollars () const {return m_dollars;}
- •Int main () {
- •If (!isHappy)
- •Int main () {
- •If (!something)
- •Перегрузка операций сравнения
- •Int main () {
- •Int m_dollars;
- •Int main () {
- •Перегрузка операторов инкремента и декремента
- •Int m_number;
- •Int main () {
- •Перегрузка операций инкремента и декремента версии постфикс
- •Int m_number;
- •Int main () {
- •Перегрузка операции индексации []
- •Почему оператор индексации [] использует возврат по ссылке?
- •Использование оператора индексации с константными объектами класса
- •Int& operator[] (const int index);
- •Int main (){
- •IntArray array;
- •Проверка ошибок
- •Int m_array[10];
- •Int& operator [] (const int index);
- •Int& IntArray::operator[] (const int index) {
- •Указатели на объекты и перегруженный оператор []
- •Передаваемый аргумент не обязательно должен быть целым числом
- •Void operator [] (std::string index);
- •Void Something::operator [] (std::string index){
- •Int main () {
- •Перегрузка операции ()
- •Int main () {
- •Void operator() ();
- •Void Matrix::operator()() {
- •Int main() {
- •Перегрузка операций преобразования типов данных
- •Int m_dollars;
- •Int getDollars () { return m_dollars; }
- •Int main () {
Введение в перегрузку операций
Мы уже знаем, что перегрузка функций обеспечивает механизм создания и выполнения вызовов функций с одним и тем же именем, но с разными параметрами. Это позволяет одной функции работать с несколькими разными типами данных (без необходимости придумывать уникальные имена для каждой из функций).
В языке C++ реализована перегрузка операций и реализована она в виде функций.
Используя функции перегрузки операции, вы можете определить свои собственные версии операций, которые будут работать с разными типами данных, но должны включать объекты классов.
Использование функции перегрузки для перегрузки операций называется коротко перегрузкой операций.
Операции, как функции
Рассмотрим следующий фрагмент:
double m = 4.0;
double p = 5.0;
std::cout << m + p << '\n';
Компилятор также предоставит встроенную версию операции плюс (+) для операндов типа double.
Выражение m + p приведет к вызову функции operator+ (m, p), а, благодаря перегрузке операции + для стандартных типов, вызовется версия для типа double.
Теперь рассмотрим, что произойдет, если мы попытаемся сложить два объекта класса:
Mystring hello = "Hello, ";
Mystring world = "World!";
std::cout << hello + world << '\n';
Как вы думаете, какой будет результат?
Наверное, вывод строки Hello, World!
Нет, результатом будет ошибка, так как класс Mystring является пользовательским типом данных, а компилятор не имеет встроенной версии функции operator+() для использования с операндами типа Mystring.
Для того, чтобы сделать то, что мы хотим, нам придется написать свою версию функции operator+ () и указать в ней алгоритм работы с операндами типа Mystring.
Использование перегруженных операций
При обработке выражения, содержащего операцию, компилятор использует следующие алгоритмы действий:
- Если все операнды являются фундаментальных типов данных, то вызывать следует встроенные соответствующие версии операций (если таковые существуют).
- Если таковых не существует, то компилятор выдаст ошибку.
- Если какой-либо из операндов является пользовательского типа данных (например, объект класса или перечисление), то компилятор будет искать версию операции, которая работает с таким типом данных.
- Если компилятор не найдет ничего подходящего, то попытается выполнить конвертацию одного или нескольких операндов пользовательского типа данных в фундаментальные типы данных, чтобы таким образом он мог использовать соответствующую встроенную операцию. Если это не сработает — компилятор выдаст ошибку.
Ограничения в перегрузке операций
Во-первых, почти любая существующая операция в языке C++ может быть перегружена.
Исключениями являются:
тернарная операция (?:);
операция sizeof;
операция разрешения области видимости (::);
операция выбора члена . и .*.
Во-вторых, вы можете перегрузить только существующие операции.
Вы не можете создавать новые или переименовывать существующие.
Например, вы не можете создать операцию ** для выполнения операции возведения в степень.
В-третьих, по крайней мере один из операндов перегружаемой операции должен быть пользовательского типа данных.
Это означает, что вы не можете перегрузить operator+ () для выполнения операции сложения значения типа int со значением типа double.
Однако вы можете перегрузить operator+ () для выполнения операции сложения значения типа int с объектом класса Mystring.
В-четвертых, изначальное количество операндов, поддерживаемых операцией, изменить невозможно.
Т.е. с бинарной операцией используются только два операнда, с унарной — только один, с тернарной — только три.
Наконец, в – пятых, все операции сохраняют свой приоритет и ассоциативность по умолчанию (независимо от того, для чего они используются), и это не может быть изменено.
Правило:
При перегрузке операций старайтесь максимально приближенно сохранять функционал операций в соответствии с их первоначальными применениями.
Для чего использовать перегрузку операций?
Вы можете перегрузить операцию + для соединения объектов вашего класса String или для выполнения операции сложения двух объектов вашего класса Fraction.
Вы можете перегрузить операцию (<< ) для вывода объекта вашего класса на экран (или записи в файл).
Вы можете перегрузить операцию равенства (==) для сравнения двух объектов класса и т.д.
Подобные применения делают перегрузку операций одной из самых полезных особенностей языка C++, так как это упрощает процесс работы с классами и открывает новые возможности.
