Содержание
- 2. Перегруженные операции Перегруженные операции (формализм) С++ позволяет переопределить большинство операций языка так, чтобы при использовании с
- 3. Перегруженные операции Перегрузка бинарных операций. x @ y – бинарная операция с объектами x и y
- 4. Перегруженные операции Перегруженные операции (пример) Пример. Перегруженные операции для строк. #pragma warning( disable : 4996 4267
- 5. Перегруженные операции Конструкторы и инверсия строк // инверсия строки str& str::operator~() { if(n>2) { // имеет
- 6. Перегруженные операции Операторы присваивания // оператор присваивания char* str& str::operator=(char *text) { if(s) delete[] s; //
- 7. Перегруженные операции Операторы сложения // дружественная функция: сложение двух объектов str str& operator+(str &x1, str &x2)
- 8. Перегруженные операции Сложение, ввод и вывод строк // дружественная функция: сложение char* и объекта str str&
- 9. Перегруженные операции Тестирование класса str // посмотрим, как работает класс str void main(void) { str a,
- 11. Скачать презентацию
Перегруженные операции
Перегруженные операции (формализм)
С++ позволяет переопределить большинство операций языка так, чтобы
Перегруженные операции
Перегруженные операции (формализм)
С++ позволяет переопределить большинство операций языка так, чтобы
Конкретно, можно перегружать следующие операции языка:
Последние четыре операции означают: индексацию, вызов функции, размещение в динамической памяти и освобождение памяти.
Для дальнейшего изложения, обозначим @ - некоторую перегружаемую операцию языка С++. Пусть x и y – объекты некоторых классов С++.
Перегрузка унарных операций.
@x – унарная операция над объектом x в префиксной форме интерпретируется как вызов функции-члена
x.operator@( ) без аргументов
или вызов friend-функции с именем
operator@( x ) с одним аргументом.
x@ – унарная операция над объектом x в постфиксной форме интерпретируется как вызов функции-члена
x.operator@( int ) , где аргумент типа int - фиктивный
или вызов friend-функции с именем
operator@( x, int) , где аргумент типа int – фиктивный.
.
+ - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |=
<< >> >>= <<= == != <= >= && || ++ -- ->* , -> [] () new delete
Перегруженные операции
Перегрузка бинарных операций.
x @ y – бинарная операция с объектами
Перегруженные операции
Перегрузка бинарных операций.
x @ y – бинарная операция с объектами
x.operator@( y ) с одним аргументом
или вызов friend-функции с именем
operator@( x , y ) с двумя аргументами.
Замечания к перегруженным операциям.
При перегрузке операций, полностью сохраняется синтаксис языка С++, в том числе приоритет и порядок выполнения операций.
Можно перегрузить операции new и delete и начать самостоятельно управлять процессами выделения и освобождения динамической памяти.
Можно перегрузить операцию индексации []. Индексы могут иметь любой тип (например, цвет, текст, др.). Это есть ассоциативные массивы.
Итераторы в контейнерах можно заменить «умными» перегруженными операциями «++» и «--», которые при обходе не позволяют выйти за пределы контейнера.
Можно переопределить операцию косвенной адресации объекта «->» для работы с «умными» указателями, которые при каждом обращении к объекту будут выполнять любую заданную вами работу.
Можно перегрузить операцию вызова функции, тогда запись вида <объект> ( <список-аргументов> ) будет рассматриваться как бинарная операция operator()(…).
Можно перегрузить операцию преобразования типа (собственный кастинг).
Перегруженные операции
Перегруженные операции (пример)
Пример. Перегруженные операции для строк.
#pragma warning( disable :
Перегруженные операции
Перегруженные операции (пример)
Пример. Перегруженные операции для строк.
#pragma warning( disable :
#include
#include
using namespace std; // пространство имен для потокового в/в
class str { // опишем класс «строки»
char* s; // указатель на символы
int n; // емкость буфера для хранения строки
public:
str() { n=1; s=NULL; } // 0-конструктор (по умолчанию)
str(const str&); // конструктор копирования
str(const char*); // конструктор общего вида
~str() { if(s) delete s; } // деструктор
str& operator~(); // операция инверсии строки
str& operator=(char*); // операция присваивания
str& operator=(str&); // операция присваивания
friend str& operator+(str&, str&); // операция сложения
friend str& operator+(str&, char*); // операция сложения
friend str& operator+(char*, str&); // операция сложения
friend istream& operator>>(istream&, str&); // операция ввода
friend ostream& operator<<(ostream&, str&); // операция вывода
};
Перегруженные операции
Конструкторы и инверсия строк
// инверсия строки
str& str::operator~() {
if(n>2) { // имеет
Перегруженные операции
Конструкторы и инверсия строк
// инверсия строки
str& str::operator~() {
if(n>2) { // имеет
char temp, *beg=s, *end=s+n-2; // рабочие указатели
while(beg
}
return *this; // результат работы – сам объект
}
// конструктор общего вида
str::str(const char *text) {
s = new char[n=strlen(text)+1]; // получим память
strcpy(s, text); // небезопасная функция!
}
// конструктор копирования
str::str(const str &x) {
s = new char[n=x.n]; // получим память
strcpy(s, x.s); // небезопасная функция!
}
Перегруженные операции
Операторы присваивания
// оператор присваивания char*
str& str::operator=(char *text) {
if(s) delete[] s; //
Перегруженные операции
Операторы присваивания
// оператор присваивания char*
str& str::operator=(char *text) {
if(s) delete[] s; //
s = new char[n=strlen(text)+1]; // получим память
strcpy(s, text); // небезопасная функция!
return *this; // результат работы – сам объект
}
// оператор присваивания str
str& str::operator=(str &x) {
if(this != &x) { // не присваиваем ли объект самому себе?
if(s) delete[] s; // освободим ранее использованную память
s = new char[n=x.n]; // получим память
strcpy(s, x.s); // небезопасная функция!
}
return *this; // результат работы – сам объект
}
Перегруженные операции
Операторы сложения
// дружественная функция: сложение двух объектов str
str& operator+(str &x1,
Перегруженные операции
Операторы сложения
// дружественная функция: сложение двух объектов str
str& operator+(str &x1,
str *sum = new str; // новый объект – в нем будет сумма строк
sum->s = new char[ sum->n = x1.n + x2.n - 1]; // получим память
strcpy(sum->s, x1.s); // строка из первого объекта
strcat(sum->s, x2.s); // цепляем строку из второго объекта
return *sum; // результат – сцепленные строки
}
// дружественная функция: сложение объекта str + char*
str& operator+(str &x, char *text) {
str *sum = new str; // новый объект – в нем будет сумма строк
sum->s = new char[ sum->n = x.n + strlen(text) ]; // получим память
strcpy(sum->s, x.s); // строка из первого объекта
strcat(sum->s, text); // цепляем строку из второго объекта
return *sum; // результат – сцепленные строки
}
Перегруженные операции
Сложение, ввод и вывод строк
// дружественная функция: сложение char* и
Перегруженные операции
Сложение, ввод и вывод строк
// дружественная функция: сложение char* и
str& operator+(char *text, str &x) {
str *sum = new str; // новый объект – в нем будет сумма строк
sum->s = new char[ sum->n = strlen(text) + x.n ]; // получим память
strcpy(sum->s, text); // строка из первого объекта
strcat(sum->s, x.s); // цепляем строку из второго объекта
return *sum; // результат – сцепленные строки
}
// дружественная функция: потоковый ввод объекта str
istream& operator>>(istream &z, str &x) {
char buf[BUFSIZ]; // рабочий буфер для ввода
z.get(buf,BUFSIZ,'\n'); // используем метод get() объекта z
x=buf; // операция присваивания для класса str уже определена
return z; // возвращаем объект класса istream
}
// дружественная функция: потоковый вывод объекта str
ostream& operator<<(ostream &z, str &x) {
return z<
Перегруженные операции
Тестирование класса str
// посмотрим, как работает класс str
void main(void) {
str
Перегруженные операции
Тестирование класса str
// посмотрим, как работает класс str
void main(void) {
str
cin>>a; // потоковый ввод
c=a+b; // сложение объектов
cout<<(a+" "+b+" "+c)<