Главная

Популярная публикация

Научная публикация

Случайная публикация

Обратная связь

ТОР 5 статей:

Методические подходы к анализу финансового состояния предприятия

Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века

Ценовые и неценовые факторы

Характеристика шлифовальных кругов и ее маркировка

Служебные части речи. Предлог. Союз. Частицы

КАТЕГОРИИ:






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




Над значением переменной типа int ваша программа может выполнять сложение, вычитание, умножение и деление. С другой стороны, использование оператора плюс для сложения двух строк лишено всякого смысла.

Перегрузка оператора состоит в изменении смысла оператора (например, оператора плюс (+), который обычно в C++ используется для сложения) при использовании его с определенным классом

Когда вы перегружаете оператор для какого-либо класса, то смысл данного оператора не изменяется для переменных других типов. Например, если вы перегружаете оператор плюс для класса string, то смысл этого оператора не изменяется, если необходимо сложить два числа.

Ниже приведено определение класса, создающее класс string. Этот класс содержит один элемент данных, который представляет собой собственно символьную строку.

Как видите, класс определяет функцию str_append, которая добавляет указанные символы к содержимому строки класса. Аналогичным образом функция chr_minus - удаляет каждое вхождение указанного символа из строки класса. Следующая программа использует класс string для создания двух объектов символьных строк и манипулирования ими.

 

#include <iostream>

#include <string>

class string

{

public:

string(char *); // Конструктор

void str_append(char *);

void chr_minus(char);

void show_string(void);

private:

char data[256];

};

string::string(char *str)

{

strcpy(data, str); // Функция strcpy() копирует cодержимое строки str в строку data.

}

void string::str_append(char *str)

{

strcat(data, str);//Объединение строк. Функция добавляет копию строки str в конец строки data.

//Нулевой символ конца строки data заменяется первым символом строки //str, и новый нуль-символ добавляется в конец уже новой строки, //сформированной объединением символов двух строк в строке

}

void string::chr_minus(char letter)

{

char temp[256];

int i, j;

for (i = 0, j = 0; data[i]; i++) // Эту букву необходимо удалить?

if (data[i]!= letter) // Если нет, присвоить ее temp

temp[j++] = data[i];

temp[j] = NULL; // Конец temp

// Копировать содержимое temp обратно в data

strcpy(data, temp);

}

void string::show_string(void) //вывод строки

{

cout << data << endl;

}

 

void main(void)

{

string title("Учимся программировать на языке C++");

string lesson("Перегрузка операторов");

title.show_string();

title.str_append(" я учусь!");

itle.show_string();

lesson.show_string();

lesson.chr_minus('p');

lesson.show_string();

}

Как видите, программа использует функцию str_append для добавления символов к строковой переменной title. Программа также использует функцию chr_minus для удаления каждой буквы " р" из символьной строки lesson. В данном случае программа использует вызовы функции для выполнения этих операций. Однако, используя перегрузку операторов, программа может выполнять идентичные операции с помощью операторов плюс (+) и минус (-).

При перегрузке оператора используйте ключевое слово C++ operator вместе с прототипом и определением функции, чтобы сообщить компилятору C++, что класс будет использовать этот метод как оператор. Например, следующее определение класса использует ключевое слово operator, чтобы назначить операторы плюс и минус функциям str_append и chr_minus внутри класса string:

class string

{

public:

string(char *); // Конструктор

void operator +(char *);

void operator -(char); ————— Определение операторов класса

void show_string(void);

private:

char data[256];

};

 

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

void string::operator +(char *str)

{

strcat(data, str);

}

Как видите, определение этой функции не содержит имени, поскольку здесь определяется перегруженный оператор класса. Для перегрузки оператора плюс программа не изменила обработку, которая осуществляется внутри функции (код этой функции идентичен коду предыдущей функции str_append). Вместо этого программа просто заменила имя функции ключевым словом operators соответствующим оператором. Следующая программа иллюстрирует использование перегружаемых операторов плюс и минус:

#include <iostream.h>

#include <string.h>

class string

{

public:

string(char *); // Конструктор

void operator +(char *);

void operator -(char);

void show_string(void);

private;

char data[256];

};

string::string(char *str)

{

strcpy(data, str);

}

void string::operator +(char *str)

{

strcat(data, str);

}

void string::operator -(char letter)

{

char temp[256];

int i, j;

for (i = 0, j = 0; data[i]; i++) if (data[il 1= letter) temp[j++] = data[i];

temp[j] = NULL;

strcpy(data, temp);

}

void string::show_string(void)

{

cout << data << endl;

}

void main(void)

{

string title("Учимся программировать на C++");

string lesson("Перегрузка операторов");

title.show_string();

title + " я учусь!";

title.show_string();

lesson.show_string();

lesson - 'P';

lesson.show_string();

}

 

Как видите, программа использует перегруженные операторы:

 

В данном случае синтаксис оператора законен, но немного непривычен. Обычно вы используете оператор плюс в выражении, которое возвращает результат, например, как в операторе some_str = title + "текст ";. Когда вы определяете оператор, C++ предоставляет вам полную свободу в отношении поведения оператора. Однако, как вы помните, ваша цель при перегрузке операторов состоит в том, чтобы упростить понимание ваших программ. Поэтому следующая программа STR_OVER.CPP немного изменяет предыдущую программу, чтобы позволить ей выполнять операции над переменными типа string, используя синтаксис, который более согласуется со стандартными операторами присваивания:

 

#include <iostream.h>

#include <string.h>

class string

{

public:

string(char *); // Конструктор

char * operator +(char *);

char * operator -(char);

void show_string(void);

private:

char data[256];

};

string::string(char *str)

{

strcpy(data, str);

}

char * string::operator +(char *str)

{

return(strcat(data, str));

}

char * string::operator -(char letter)

{

char temp[256];

int i, j;

for (i = 0, j = 0; data[i]; i++) if (data[i] 1= letter) temp[j++] = data[i];

temp[j] = NULL;

return(strcpy(data, temp));

}

void string::show_string(void)

{

cout << data << endl;

}

void main(void)

{

string title("Учимся программировать на C++");

string lesson("Перегрузка операторов");

title.show_string();

title = title + " я учусь";

title.show_string();

lesson.show_string();

lesson = lesson - '?';

lesson.show_string();

}

Используя перегрузку, ваши программы могут перегрузить операторы равенства (==), неравенства (!=) или другие операторы сравнения.

В класс нужно добавить

int operator ==(string);

и

int string::operator ==(string str)

{

int i;

for (i = 0; data[i] == str.data[i]; i++)

if ((data[i] == NULL) && (str.data[i] == NULL)) return(1); // Равно

return (0); //He равно

}

И тогда в main можно писать такое:

if (title == lesson) cout << "title и lesson равны" << endl;

Как видите, перегружая операторы подобным образом, вы упрощаете понимание ваших программ.

ОПЕРАТОРЫ, КОТОРЫЕ ВЫ HE МОЖЕТЕ ПЕРЕГРУЗИТЬ

Оператор Назначение Пример

. Выбор элемента object.member

.* Указатель на элемент object.*member

:: Разрешение области видимости classname::member

?: Условный оператор сравнения с = (а > b)? а: b;

Шаблоны функций.

При создании функций иногда возникают ситуации, когда две функции выполняют одинаковую обработку, но работают с разными типами данных (например, одна использует параметры типа int, а другая типа float).

Например, ниже определен шаблон для функции с именем max, которая возвращает большее из двух значений:

template<class Т> Т mах(Т а, Т b)

{

if (а > b) return(а);

else return(b);

}

Буква T в данном случае представляет собой общий тип шаблона. После определения шаблона внутри вашей программы вы объявляете прототипы функций для каждого требуемого вам типа. В случае шаблона max следующие прототипы создают функции типа float и int.

float max(float, float);

int max(int, int);

Когда компилятор C++ встретит эти прототипы, то при построении функции он заменит тип шаблона T указанным вами типом. В случае с типом float функция max после замены примет следующий вид:

float max(float a, float b)

{

if (a > b) return(a);

else return(b);

}

Следующая программа использует шаблон max для создания функции типа int и float.

#include <iostream>

template<class T> Т mах(Т а, Т b)

{

if (a > b) return(a);

else return(b);

}

float max(float, float);

int max(int, int);

void main(void)

{

cout << "Максимум 100 и 200 равен " << max(100, 200) << endl;

cout << "Максимум 5.4321 и 1.2345 равен " << max(5.4321, 1.2345) << endl;

}

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

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

Предыдущее определение шаблона для функции max использовало единственный общий тип Т. Очень часто в шаблоне функции требуется указать несколько типов. Например, следующие операторы создают шаблон для функции show_array, которая выводит элементы массива. Шаблон использует тип Т для определения типа массива и тип Т1 для указания типа параметра count:

template<class T, class T1> void show_array(T *array,T1 count)

 

{

T1 index;

for (index =0; index < count; index++) cout << array[index] << ' ';

cout << endl;

}

Как и ранее, программа должна указать прототипы функций для требуемых типов:

void show_array(int *, int);

void show_array(float *, unsigned);

Следующая программа использует шаблон для создания функций, которые выводят массивы типа int и типа float.

#include <iostream>

template<class T, class T1> void show_array(T *array,T1 count)

{

T1 index;

for (index =0; index < count; index++) cout << array[index] “ ' ';

cout << endl;

}

void show_array(int *, int);

void show_array(float *, unsigned);

void main(void)

{

int pages[] = { 100, 200, 300, 400, 500 };

float pricesH = { 10.05, 20.10, 30.15 };

show_array(pages, 5);

show_array(prices, 3);

}






Не нашли, что искали? Воспользуйтесь поиском:

vikidalka.ru - 2015-2024 год. Все права принадлежат их авторам! Нарушение авторских прав | Нарушение персональных данных