Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.86
BTR
8 / 8 / 1
Регистрация: 01.11.2010
Сообщений: 157
#1

operator - C++

24.01.2011, 22:20. Просмотров 1706. Ответов 36
Метки нет (Все метки)

Всем привет, опять непонятка в книге, дошел до оператора operator и ничего не понял, для чего он нужен, что он делает, то есть как он перегружает символы и как им пользоваться, привидите пожалуйста пример, заранее благодарен!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.01.2011, 22:20     operator
Посмотрите здесь:

C++ operator =
C++ operator[]
C++ operator++
operator< C++
C++ operator=
C++ operator[]
Operator>> C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ISergey
Maniac
Эксперт С++
1347 / 880 / 52
Регистрация: 02.01.2009
Сообщений: 2,645
Записей в блоге: 1
24.01.2011, 22:33     operator #2
http://www.cplusplus.com/doc/tutorial/classes2/
BTR
8 / 8 / 1
Регистрация: 01.11.2010
Сообщений: 157
24.01.2011, 22:39  [ТС]     operator #3
у меня с англ проблема =(
asics
Freelance
Эксперт C++
2846 / 1783 / 144
Регистрация: 09.09.2010
Сообщений: 3,842
24.01.2011, 22:46     operator #4
Цитата Сообщение от BTR Посмотреть сообщение
у меня с англ проблема =(
http://translate.google.com.ua/#
Escapable
54 / 54 / 1
Регистрация: 09.11.2010
Сообщений: 120
24.01.2011, 23:08     operator #5
BTR, operator служит для перегрузки операторов (+, -, ++, -- и т.д).
Пример:
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>
using namespace std;
 
class A
{
    int x, y, z;
public:
    A() { x = y = z = 0; }
    A(int i, int j, int k) { x = i; y = j; z = k; }
 
    A operator+(A op);  
    A operator-(A op);
 
    void show();
};
 
A A::operator+(A op)
{
    ThreeD temp;
    
    temp.x = x + op.x;
    temp.y = y + op.y;
    temp.z = z + op.z;
 
    return temp; 
}
 
A A::operator-(A op)
{
    A temp;
    
    temp.x = x - op.x;
    temp.y = y - op.y;
    temp.z = z - op.z;
 
    return temp;
}
 
void A::show()
{
    cout << x << ", ";
    cout << y << ", ";
    cout << z << endl;
}
 
int main()
{
    A a(1, 2, 3), b(10, 10, 10), c;
    с = a + b; // здесь выполняется перегрузка
    c.show();
    
    с = a - b; // и здесь тоже
    c.show();
    
return 0;
}
Т.е. если бы мы не перегрузили операторы + и -, то мы бы не смогли сложить\отнять объекты a и b.

Сам сейчас изучаю данную тему, как по мне, довольно специфическую.
silent_1991
Эксперт С++
4956 / 3032 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
25.01.2011, 09:28     operator #6
Главное - понять, что перегрузка операторов ничем не отличается от написания обычных функций. Вы сам пишете алгоритм, по которому будет выполняться тот или иной оператор (можно, например, оператор + перегрузить так, чтобы он умножал и т.д. - всё в ваших руках). Вы даже можете явно выполнить оператор как вызов функции (например, с = a.operator+(b); - именно такую конструкцию воспринимает компилятор, когда видит запись c = a + b. По себе знаю, пока считаешь перегрузку операций чем-то незаурядным, сверхъестественным - сложнее всё это понимать, чем когда до тебя доходит, что это тот же процесс написания функций.
BTR
8 / 8 / 1
Регистрация: 01.11.2010
Сообщений: 157
27.01.2011, 18:01  [ТС]     operator #7
все равно не пойму, как им пользоваться?

Добавлено через 19 секунд
можете привести более легкий пример?
silent_1991
Эксперт С++
4956 / 3032 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
27.01.2011, 19:49     operator #8
Вот мини-примерчик:

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
65
66
67
68
69
70
71
72
#include <iostream>
 
class A
{
public:
    A(int = 0);
    
    friend A operator+(const A &, const A &);
    friend A operator-(const A &, const A &);
    friend A operator*(const A &, const A &);
    friend A operator/(const A &, const A &);
 
    friend std::istream &operator>>(std::istream &, A &);
    friend std::ostream &operator<<(std::ostream &, const A &);
 
private:
    int _a;
};
 
A::A(int a):
_a(a)
{
}
 
A operator+(const A &lhs, const A &rhs)
{
    return A (lhs._a + rhs._a);
}
 
A operator-(const A &lhs, const A &rhs)
{
    return A (lhs._a - rhs._a);
}
 
A operator*(const A &lhs, const A &rhs)
{
    return A (lhs._a * rhs._a);
}
 
A operator/(const A &lhs, const A &rhs)
{
    return A (lhs._a / rhs._a);
}
 
std::istream &operator>>(std::istream &input, A &rhs)
{
    return input >> rhs._a;
}
 
std::ostream &operator<<(std::ostream &output, const A &rhs)
{
    return output << rhs._a;
}
 
int main()
{
    A a1, a2;
 
    std::cin >> a1 >> a2;
 
    std::cout << a1 + a2 << std::endl;
    std::cout << a1 - a2 << std::endl;
    std::cout << a1 * a2 << std::endl;
    std::cout << a1 / a2 << std::endl;
    std::cout << std::endl;
    std::cout << operator+(a1, a2) << std::endl;
    std::cout << operator-(a1, a2) << std::endl;
    std::cout << operator*(a1, a2) << std::endl;
    std::cout << operator/(a1, a2) << std::endl;
 
    return 0;
}
Как видите, я наглядно показал, что написание перегруженной версии оператора ничем не отличается от написания функции. Всё чисто логически. Если мы складываем два объекта типа A, то результат должен также иметь тип A - значит, тип возвращаемого значения будет A. Имя нашей функции (например, для сложения) - operator+. Т.е. мы можем явно вызвать эту функцию стандартно, написав имя и передаваемые параметры (operator+(a1, a2)), а можем неявно (тогда вызов функции подставит за нас компилятор) - просто написав a1 + a2. А реализация самой функции тоже чисто логически (это я всё к тому, что нет жёстких правил, тело вы можете написать какое угодно, а похожесть перегрузок возникает не из-за того, что всем талдычат некий шаблон, от которого нельзя отступать, а потому, что такой шаблон сам появляется, и он практически идеален, чтобы от него отступать) - результатом должен быть объект типа A. При этом на неком уровне абстракции он должен представлять сумму двух объектов типа A. В нашем случае всё интуитивно, объект - обёртка для целого числа, значит результатом сложения двух таких объектов должен быть объект, в котором хранится сумма этих чисел, что мы и делаем, создавая объект и инициализируя его значением rhs._a + lhs._a, а затем возвращая его в качестве результата сложения.
ForEveR
27.01.2011, 20:35
  #9

Не по теме:

silent_1991, А зачем френдами то?? Не, тоже вариант конечно, но имхо предпочтительнее через глобалы... Все же это вспомогательные функции.

volovzi
267 / 169 / 8
Регистрация: 14.03.2010
Сообщений: 501
27.01.2011, 20:37     operator #10
ForEveR, наверное, чтобы иметь доступ к скрытым переменным.
silent_1991
Эксперт С++
4956 / 3032 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
27.01.2011, 20:39     operator #11

Не по теме:

ForEveR, а как не друзьям обращаться к приватным членам? Не через геты же)))



Добавлено через 44 секунды

Не по теме:

volovzi, ога, опередили)))

ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
27.01.2011, 23:55     operator #12

Не по теме:

silent_1991, А почему не через геты собственно? По-моему это правильнее. Инкапсуляция все же.



Добавлено через 27 минут

Не по теме:

Хотя впринципе что-то я перебарщиваю) не суть как это писать)

silent_1991
28.01.2011, 05:59
  #13

Не по теме:

ForEveR, ну не знаю... Я вообще раньше мемберами делал, потом переключился на френды, удобнее работать, когда у тебя есть переменные left и right, а не *this и right . В примере с числами ещё ничего, а вот когда длинная арифметика или матрицы умножаешь - путаешься, у какой матрицы взять размер, а у какой очередной элемент)))

taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
28.01.2011, 06:07     operator #14
Цитата Сообщение от ForEveR Посмотреть сообщение
предпочтительнее через глобалы
Через глобалы нельзя, френдами не надо, а надо через члены.
silent_1991
Эксперт С++
4956 / 3032 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
28.01.2011, 06:10     operator #15
Цитата Сообщение от taras atavin Посмотреть сообщение
френдами не надо
Это ещё почему? А передачу/извлечение из потока вы как членами сделаете? Да и кучу других операторов, где первый операнд может оказаться не объектом данного класса? Я всё-таки предпочитаю френды, уже написал, почему.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
28.01.2011, 06:19     operator #16
Я много раз сам делал френдовые операторы, но в данном случае надо членами, так как оба операнда - экземпляры одного класса.

Добавлено через 6 минут
Кстати, у меня бывает, что воообще ни один операнд, например, оператора умножения не является объектом какого либо класса, при этом они имеют разные типы между собой, а тип возвращаемого значения вообще третий. Например, я часто умножаю double на enum, а возвращаю объект. В таких случаях никуда от френда.
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
28.01.2011, 07:03     operator #17
taras atavin, С чего вдруг через глобалы нельзя? Мне как раз такой подход больше нравится...
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
28.01.2011, 07:05     operator #18
А как ты собираешься получить доступ к закрытым членам?
silent_1991
Эксперт С++
4956 / 3032 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
28.01.2011, 08:02     operator #19

Не по теме:

taras atavin, уже обсудили же, сеты/геты решают в этом случае)))
А почему вы так упёрлись в члены и так категорично заявляете "нельзя френдами, если можно мемберами"?



Добавлено через 1 минуту

Не по теме:

ForEveR, taras atavin, нормально, три типа спорят, и каждый проталкивает способ, который ему больше нравится)))
Мы же знаем, господа, что это ни к чему не приведёт)))

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.01.2011, 08:21     operator
Еще ссылки по теме:

operator >> C++
operator() C++
C++ Operator=
C++ Operator +
C++ Operator*

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

Или воспользуйтесь поиском по форуму:
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
28.01.2011, 08:21     operator #20
Цитата Сообщение от silent_1991 Посмотреть сообщение
"нельзя френдами, если можно мемберами"?
Нельзя обычными глобальными функциями. А френдами можно, но в данном случае не нужно. Что они в данном конкретном случае дают про сравнению с членами? Только то, что при наследовании будет легче запутаться.
Yandex
Объявления
28.01.2011, 08:21     operator
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru