Перегрузка в C++: функции, оператора

Лучшие IDE для C и C++ Программирование и разработка

Лучшие IDE для C и C++

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

Арифметические операторы обычно используются для арифметических операций. Разве не хорошо иметь +, соединять две строки? Включение этого называется перегрузкой оператора арифметического сложения для строк.

Оператор инкремента ++ добавляет 1 к int или float. При работе с указателями он не добавляет к указателю 1. Это заставляет указатель указывать на следующий последовательный объект в памяти. Итератор указывает на следующий объект в связанном списке, но объекты связанного списка находятся в разных местах памяти (а не в последовательных областях). Было бы неплохо перегрузить оператор инкремента для итератора, чтобы увеличивать, но указывать на следующий элемент в связанном списке?

В этой статье объясняется перегрузка в C ++. Он разделен на две части: перегрузка функции и перегрузка оператора. Для понимания остальной части статьи необходимо уже иметь базовые знания C ++.

Перегрузка функций

Следующая функция добавляет два целых числа и возвращает целое число:

int add(int no1, int no2)
{
int sum = no1 + no2;
return sum;
}

The prototype of this function is:

int add(int no1, int no2);

The prototype of a function in the header of the function, ending with a semicolon. The following function with the same name, but with a different prototype, would add three floats and return a float:

float add(float no1, float no2, float no3)
{
float sum = no1 + no2 + no3;
return sum;
}

Как компилятор определяет, какую функцию вызывать, если две или более функций имеют одинаковое имя? Компилятор использует количество аргументов и типы аргументов, чтобы определить, какую функцию вызывать. Список параметров перегруженных функций должен различаться по их количеству и / или типам параметров. Итак, вызов функции,

int sm = add(23);

вызовет целочисленную функцию, а вызов функции

float sme = add(2.33.42.0);

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

Следующая программа приводит в действие указанные выше сегменты кода:

#include <iostream>
using namespace std;

int add(int no1, int no2)
{
int sum = no1 + no2;
return sum;
}

float add(float no1, float no2, float no3)
{
float sum = no1 + no2 + no3;
return sum;
}

int main()
{
int sm = add(23);
cout<<sm<<\n;
float sme = add(2.33.42.0);
cout<<sme<<\n;

return 0;
}

Результат:
5
7,7

Перегрузка оператора

Арифметические операторы используются для перегрузки операций в типах классов. Итератор — это тип класса. Операторы инкремента и декремента используются для перегрузки операций итератора.

Пример перегрузки оператора класса String

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

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

#include <iostream>
using namespace std;

class spring
{
public:
//data members
char val[100];
int n;
char concat[100];
//member functions
spring (char arr[])
{
for (int i=0; i<100; ++i) {
val[i] = arr[i];
if (arr[i]  == \0)
break;
}
int i;
for (i=0; i<100; ++i) if (arr[i]  == \0) break;
= i;
}
spring operator+(spring& st) {
int newLen = n + st.n;
char newStr[newLen+1];
for (int i=0; i<n; ++i) newStr[i] = val[i];
for (int i=n; i<newLen; ++i) newStr[i] = st.val[in];
newStr[newLen] = \0;
spring obj(newStr);
return obj;
}
};

int main()
{
char ch1[] = «I hate you! «; spring str1(ch1);
char ch2[] = «But she loves you!»; spring str2(ch2);
char ch3[] = «one»; spring str3(ch3);
str3 = str1 + str2;
cout<<str3.val<<\n;

return 0;
}

Значение str1 — «Я тебя ненавижу!». Значение str2 — «Но она тебя любит!». А также, значение str3, то есть str1 + str2, является выходом:

«Я ненавижу тебя! Но она тебя любит!» который представляет собой конкатенацию двух строковых литералов. Сами строки представляют собой экземпляры объектов.

Определение операторной функции находится внутри описания (определения) строкового класса. Он начинается с возвращаемого типа «пружина» вместо «струна». Специальное имя «оператор, следуйте за этим». После этого идет символ оператора (подлежащего перегрузке). Затем идет список параметров, который на самом деле является списком операндов. + — это бинарный оператор: это означает, что он принимает левый и правый операнды. Однако, согласно спецификации C ++, в списке параметров здесь есть только правильный параметр. Затем идет тело операторной функции, которое имитирует поведение обычного оператора.

Согласно спецификации C ++, определение оператора + принимает только параметр правого операнда, потому что остальная часть описания класса является параметром левого операнда.

В приведенном выше коде только определение функции operator + () связано с перегрузкой +. Остальная часть кода класса — это обычная кодировка. Внутри этого определения два строковых литерала объединены в массив newStr []. После этого фактически создается новый строковый объект (экземпляр) с использованием аргумента newStr []. В конце определения функции operator + () возвращается вновь созданный объект, имеющий объединенную строку.

В функции main () добавление выполняется с помощью оператора:

str3 = str1 + str2;

Где str1, str2 и str3 — строковые объекты, которые уже были созданы в main (). Выражение «str1 + str2» с его + вызывает функцию-член operator + () в объекте str1. Функция-член operator + () в объекте str1 использует str2 в качестве аргумента и возвращает новый объект с (разработанной) объединенной строкой. Оператор присваивания (=) полного оператора заменяет содержимое (значения переменных) объекта str3 содержимым возвращенного объекта. В функции main () после добавления значение элемента данных str3.val больше не равно «единице»; это сложенная (сложенная) строка: «Я тебя ненавижу! Но она тебя любит!». Функция-член operator + () в объекте str1 использует строковый литерал своего собственного объекта и строковый литерал своего аргумента str2 для получения объединенного строкового литерала.

Перегрузка оператора итератора

При работе с итератором задействованы как минимум два объекта: связанный список и сам итератор. Фактически задействованы как минимум два класса: класс, из которого создается связанный список, и класс, из которого создается итератор.

Связанный список

Схема для объекта двусвязного списка:

Этот список состоит из трех элементов, но их может быть больше. Три элемента здесь являются элементами целых чисел. Первый имеет значение 14; следующий имеет значение 88; а последний имеет значение 47. Каждый элемент здесь состоит из трех последовательных местоположений.

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

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

В массиве оператор инкремента (++) увеличивает указатель на физически следующее местоположение. В списке элементы не находятся в последовательных областях памяти. Итак, оператор инкремента может быть перегружен, переместив итератор (указатель) с одного элемента на логически следующий элемент. Такая же проекция применяется к оператору декремента (-).

Прямой итератор — это итератор, который при включении указывает на следующий элемент. Обратный итератор — это итератор, который при включении указывает на предыдущий элемент.

Перегрузка ++ ad —

Перегрузка этих операторов выполняется в описании (определении) класса итератора.

Синтаксис прототипа префикса перегрузки оператора приращения:

ReturnType operator++();

Синтаксис прототипа перегрузки оператора инкремента, postfix, следующий:

ReturnType operator++(int);

Синтаксис прототипа перегрузки оператора декремента, префикса, следующий:

ReturnType operator();

Синтаксис прототипа перегрузки оператора инкремента, postfix, следующий:

ReturnType operator(int);

Заключение

Перегрузка означает придание функции или оператора разного значения. Функции перегружены в той же области. Что отличает перегруженные функции, так это количество и / или типы параметров в их списках параметров. В некоторых случаях, когда количество параметров одинаковое, но с разными типами, компилятор отклоняет перегрузку — см. Ниже. Многие обычные операторы могут быть перегружены в классах, из которых создаются экземпляры объектов. Для этого специальной функции с именем operator в описании класса присваивается тип возвращаемого значения, список параметров и тело. и тело.

Читайте также:  Основы программирования для начинающих
Оцените статью
bestprogrammer.ru
Добавить комментарий