Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.66/91: Рейтинг темы: голосов - 91, средняя оценка - 4.66
132 / 99 / 11
Регистрация: 21.11.2007
Сообщений: 544
1

Переопределение операторов внутри пользовательских классов

28.11.2007, 11:06. Показов 18123. Ответов 2
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Проблема: Например, создан класс комплексных чисел (или вообще любой).. Как внутри него правильно переопределять операторы (напр., арифемтику), чтобы не пользоваться более громоздким вызовом функций.

По просьбе администратора создаю отдельную тему... думаю это оправдано.
Новичкам (и мне в том числе ) трудно осваивать в этой области официальную литературу. Поэтому если у кого есть с этим опыт - поделитесь пожалуйста (такскать "ПОДДЕРЖИ ОТЕЧЕСТВЕННЫЙ ПРОГПРОМСТРОЙ").
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.11.2007, 11:06
Ответы с готовыми решениями:

Возможно ли переопределение операторов для пользовательских типов?
Собственно преследуемая цель: Определить свой тип int - myint. Переопределить для него операторы...

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

Переопределение операторов
Плиз помогите сделать задачку.. Написать класс StrangeInt для которого нижеследующий код ...

Переопределение операторов С++
Помогите разобраться с переопределением операторов, как что и куда записывается, какие параметры....

2
Администратор
83618 / 52196 / 244
Регистрация: 10.04.2006
Сообщений: 13,426
28.11.2007, 11:28 2
Из википедии:
Перегрузка операций

В программировании, перегрузка операторов — определённый случай полиморфизма, в котором некоторые или все операторы, такие как +, = или == имеют различное значение в зависимости от типов их параметров. Операторы не обязаны всегда быть символами. Иногда перегрузки определены языком, иногда программист может осуществить её для новых типов.

Перегрузка операторов — обычно только «синтаксический сахар». Тем не менее, эта функция полезна, потому что она позволяет разработчику программировать более естественным образом. Также перегрузка операторов делает поведение пользовательских типов более похожим на поведение встроенных. Того же самого эффекта можно добиться, используя функции; к примеру, рассмотрим для целых чисел a, b, c:

a + b Ч c

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

operator_add_integers (a, operator_multiply_integers (b,c))

Критика

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

a << 1;

возвратит удвоенное значение, если a является целой переменной. Однако, если a является выходным потоком, та же строка выведет в этот поток строку «1».

Поскольку перегрузка оператора позволяет программисту изменять обычную семантику оператора, обычно считается хорошей практикой использовать её с осторожностью. Программисты, одобряющие перегрузку операторов, обычно отвечают на это, что то же самое относится и к перегрузке функций. Более того, даже в отсутствии перегрузки, программист может определить функцию, которая выполняет совсем не то, что подразумевается в её названии. Другая, более тонкая проблема с операторами — то, что может ожидаться выполнение определённых правил математики. Например, a + b обычно (но не всегда) означает то же самое, что b + a, но «один» + «два» отличается от «два» + «один» на языках, где оператор + перегружен для конкатенации строк.
1
Администратор
83618 / 52196 / 244
Регистрация: 10.04.2006
Сообщений: 13,426
28.11.2007, 11:31 3
Лучший ответ Сообщение было отмечено dioxidin как решение

Решение

Еще откуда-то:
Перегрузка операторов в С++

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

Перегрузка оператора состоит в изменении смысла оператора (например, оператора плюс (+), который обычно в C++ используется для сложения) при использовании его с определенным классом. В данном уроке вы определите класс string и перегрузите операторы плюс и минус. Для объектов типа string оператор плюс будет добавлять указанные символы к текущему содержимому строки. Подобным образом оператор минус будет удалять каждое вхождение указанного символа из строки. К концу данного урока вы изучите следующие основные концепции:

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

Перегрузка операторов может упростить наиболее общие операции класса и улучшить читаемость программы. Найдите время для эксперимента с программами, представленными в этом уроке, и вы обнаружите, что перегрузка операторов выполняется очень просто.
ПЕРЕГРУЗКА ОПЕРАТОРОВ ПЛЮС И МИНУС

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

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

C++
1
2
3
4
5
6
7
8
9
10
11
    class string
 
    {
    public:
       string(char *); // Конструктор
       void str_append(char *);
       void chr_minus(char);
       void show_string(void);
    private:
       char data[256] ;
    };
Как видите, класс определяет функцию str_append, которая добавляет указанные символы к содержимому строки класса. Аналогичным образом функция chr_minus - удаляет каждое вхождение указанного символа из строки класса. Следующая программа STRCLASS.CPP использует класс string для создания двух объектов символьных строк и манипулирования ими.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
    #include <iostream.h>
 
    #include <string.h>
 
    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);
    }
 
    void string::str_append(char *str)
 
    {
       strcat(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:

C++
1
2
3
4
5
6
7
8
9
10
    class string
 
    {
    public:
       string(char *); // Конструктор
       void operator +(char *);
       void operator -(char); —————Определение операторов класса void show_string(void);
    private:
       char data[256];
    };
Как видите, класс перегружает операторы плюс и минус. Как уже упоминалось, когда класс перегружает оператор, он должен указать функцию, которая реализует операцию, соответствующую этому оператору. В случае оператора плюс определение такой функции становится следующим:
C++
1
2
3
4
5
    void string::operator +(char *str)
 
    {
       strcat(data, str);
    }
Как видите, определение этой функции не содержит имени, поскольку здесь определяется перегруженный оператор класса. Для перегрузки оператора плюс программа не изменила обработку, которая осуществляется внутри функции (код этой функции идентичен коду предыдущей функции str_append). Вместо этого программа просто заменила имя функции ключевым словом operators соответствующим оператором. Следующая программа OPOVERLD.CPP иллюстрирует использование перегружаемых операторов плюс и минус:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
    #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();
    }
Как видите, программа использует перегруженные операторы:

title + " я учусь!"; // Добавить текст " я учусь!"

lesson - 'р'; // Удалить букву 'р'

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

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
    #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();
    }
Изменив перегруженные операторы плюс и минус таким образом, чтобы они возвращали указатель на символьную строку, программа может теперь использовать эти операторы в привычном для оператора присваивания виде:

title = title + " учимся программировать!";

lesson = lesson - 'р';

Второй пример

При создании ваших собственных типов данных с помощью классов наиболее общей операцией будет проверка, являются ли два объекта одинаковыми. Используя перегрузку, ваши программы могут перегрузить операторы равенства (==), неравенства (!=) или другие операторы сравнения. Следующая программа COMP_STR.CPP добавляет новый оператор в класс string, который проверяет, равны ли два объекта string. Используя перегрузку операторов, ваши программы могут проверять, содержат ли строковые объекты одинаковые строки, как показано ниже:

if (some_string == another_string)

Ниже приведена реализация программы COMP_STR.CPP:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
    #include <iostream.h>
 
    #include <string.h>
 
    class string
 
    {
    public:
       string(char *); // конструктор
       char * operator +(char *);
       char * operator -(char);
       int operator ==(string);
       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));
    }
 
    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 равно
    }
 
    void string::show_string(void)
 
    {
       cout << data << endl;
    }
 
    void main(void)
 
    {
       string title( "Учимся программировать на C++");
       string lesson("Перегрузка операторов");
       string str( "Учимся программировать на C++");
       if (title == lesson) cout << "title и lesson равны" << endl;
       if (str == lesson) cout << "str и lesson равны" << endl;
       if (title == str) cout << "title и str равны" << endl;
    }
Как видите, перегружая операторы подобным образом, вы упрощаете понимание ваших программ.

ЧТО ВАМ НЕОБХОДИМО ЗНАТЬ

Перегрузка операторов — это возможность назначать новый смысл операторам при использовании их с определенным классом. Используя перегрузку операторов, вы можете повысить удобочитаемость ваших программ и облегчить их понимание, выражая операции класса более понятным образом. Из урока 25 вы узнаете, как разделить данные между объектами с помощью элемента static и как использовать методы класса, когда никакие объекты класса не объявляются. До изучения урока 25 убедитесь, что вы освоили следующее:

1. Чтобы перегрузить оператор, вы должны определить класс, которому оператор будет назначен.
2. Когда вы перегружаете оператор, перегрузка действует только для класса, в котором он определяется. Если программа использует оператор с неклассовыми переменными (например, переменными типа int или float), используется стандартное определение оператора.
3. Чтобы перегрузить оператор класса, используйте ключевое слово C++ operator для определения метода класса, который C++ вызывает каждый раз, когда переменная класса использует оператор.
4. C++ не позволяет вашим программам перегружать оператор выбора элемента (.), оператор указателя на элемент (.*), оператор разрешения области видимости (::) и условный оператор сравнения (?:).
3
28.11.2007, 11:31
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.11.2007, 11:31
Помогаю со студенческими работами здесь

Переопределение операторов
Доброго времени суток.. В древние времена, когда ещё жили мамонты, ковырял я потихоньку плюсы.....

Переопределение операторов
Здравствуйте. Проблема вот какая. Есть два класса. Класс &quot;Меандр&quot;, и класс &quot;Синус&quot;. Оба эти класса...

переопределение операторов
Писал прогу с переопределнием операторов, всё работало, теперь когда мне понадобилась та либа, в...

Переопределение операторов
Здравствуйте! Подскажите пожалуйста... Мне в задании надо переопределить оператор...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru