Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
0495976_C19D7_shpory_s.doc
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
1.82 Mб
Скачать

58. Перегрузка операций

В языке С++ определены множества операций над переменными стандартных типов, такие как +, -, *, / и т.д. Каждую операцию можно применить к операндам определенного типа.

К сожалению, лишь ограниченное число типов непосредственно поддерживается любым языком программирования. Например, С и С++ не позволяют выполнять операции с комплексными числами, матрицами, строками, множествами. Однако, все эти операции можно выполнить через классы в языке С++.

Рассмотрим пример.

Пусть заданы множества А и В: А = { а1, а2, а3 }; В = { a3, a4, a5 }, и мы хотим выполнить операции объединения (+) и пересечения (*) множеств.

А + В = { a1, a2, a3, a4, a5 } А * В = { a3 }.

Можно определить класс Set - "множество" и определить операции над объектами этого класса, выразив их с помощью знаков операций, которые уже есть в языке С++, например, + и *. В результате операции + и * можно будет использовать как и раньше, а также снабдить их дополнительными функциями (объединения и пересечения). Как определить, какую функцию должен выполнять оператор: старую или новую? Очень просто – по типу операндов. А как быть с приоритетом операций? Сохраняется определенный ранее приоритет операций. Для распространения действия операции на новые типы данных надо определить специальную функцию, называемую "операция-функция" (operator-function). Ее формат:

тип_возвр_значения operator знак_операции(специф_параметров)

{операторы_тела_функции}

При необходимости может добавляться и прототип:

тип_возвр_значения operator знак_операции(специф_параметров);

Если принять, что конструкция operator знак_операции есть имя некоторой функции, то прототип и определение операции-функции подобны прототипу и определению обычной функции языка С++. Определенная таким образом операция называется перегруженной (overload).

Чтобы была обеспечена явная связь с классом, операция-функция должна быть либо компонентом класса, либо она должна быть определена в классе как дружественная и у нее должен быть хотя бы один параметр типа класс (или ссылка на класс). Вызов операции-функции осуществляется так же, как и любой другой функции С++: operator @. Однако разрешается использовать сокращенную форму ее вызова: a @ b, где @ - знак операции.

59. Перегрузка для труктур

Приведем еще один пример, демонстрирующий перегрузку операций извлечения и вставки в поток, на этот раз для структуры:

struct info {

char *name;

double val;

char *units;

info(){

val=0;

name = new char [30];

units = new char [30];

name[0]=units[0]=0;

}};

ostream& operator << (ostream& s, info &m){ // Вывод info в s

s << m.name << " "<< m.val <<" "<< m.units<< "\n";

return s;}

Oперация >> может быть перегружена следующим образом:

istream& operator >> (istream& s, info &m){ // Ввод в info

s.width(30); s >> m.name;

char c;

while((c = s.get())!= ' ' && c!='\t' && c!='\n');

s.putback©;

s.width(30);

s >> m.val;

s.width(30);

s >> m.units;

return s;

}

Для считывания строки ввода, такой как "Resistance 300 Ohm", можно использовать следующую запись:

void main(){

clrscr();

info m;

cout<< "Введите наименование величины, ее значение \n";

cout<< " и единицу измерения (и нажмите Enter.):\n";

cin >> m; // Переопределенная операция >>

cout << m; // Переопределенная операция <<

}

При выполнении этой программы диалог на экране монитора может выглядеть следующим образом:

Введите наименование величины, ее значение

и единицу измерения (и нажмите Enter.):

Resistance 300 Ohm

Resistance 300 Ohm [/spoiler]

60. Перегрузка функций позволяет вашим программам определять несколько функций с одним и тем же именем и типом возвращаемого значения. Например, следующая программа перегружает функцию с именем add_values. Первое определение функции складывает два значения типа int. Второе определение функции складывает три значения. В процессе компиляции C++ корректно определяет функцию, которую необходимо использовать:

#include <iostream.h>

int add_values(int a,int b){    return(a + b); )

int add_values (int a, int b, int c)

(    return(a + b + c); )

void main(void){    cout << "200 + 801 = " << add_values(200, 801) << endl;    cout << "100 + 201 + 700 = " << add_values(100, 201, 700) << endl; }

Как видите, программа определяет две функции с именами add_values Первая функция складывает два значения типа int, в то время как вторая складывает три значения. Вы не обязаны что-либо предпринимать специально для того, чтобы предупредить компилятор о перегрузке, просто используйте ее. Компилятор разгадает, какую функцию следует использовать, основываясь на предлагаемых программой параметрах.

Шаблонные функции: Объявление:

template <class T> // или template <typname T>;

T max(T val1, T val2, T val3){

T max = val1;

if(val2 > max) max=val2;

if(val3 > max) max=val3;

return max; }

Использование:

int rez = max(1,10,3);

float rez = max(0.5,9.99,6.78);

Шаблоны и друзья:

friend void f1(); //друг любого класса

friend void f2(x<T> &); //друг конкретного класса

friend void A::f4(); //друг любого класса

friend void C<T>::f5(x<T> &); //друг конкретного класса

friend class Y; //класс Y дружественен любому классу

friend class Z<T>; //класс Y дружественен конкретному классу

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]