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

Перезагрузка operator == - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.71
Scorpion93
 Аватар для Scorpion93
2 / 2 / 0
Регистрация: 31.10.2010
Сообщений: 120
13.11.2011, 02:40     Перезагрузка operator == #1
Тренируюсь и пишу клас комплексных чисел. Проблема с перезагнрузкой оператора сравнения да и другие перезагрузки не хотят использоваться. Как решить эту проблему? Ведь желательно передавать константные ссылки? Но к ним уже стает проблематично использовать перезагрузки..

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <math.h>
 
using namespace std;
class MyComplex
{
private:
    double a;
    double b;
public:
    MyComplex(void);
    MyComplex(double,double);
    void ConsoleInput();
    void ConsoleOutput();
    string Output();
    bool operator==(double);
    MyComplex operator +(const MyComplex &);
    MyComplex operator -(const MyComplex &);
    MyComplex operator *(const MyComplex &);
    MyComplex operator /(const MyComplex &);    
    ~MyComplex(void);
};
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 "StdAfx.h"
#include "MyComplex.h"
 
 
MyComplex::MyComplex(void): a(0),b(0)
{   
     
}
MyComplex::~MyComplex(void)
{
}
MyComplex::MyComplex(double x,double y):a(x),b(y)
{
}
void MyComplex::ConsoleInput()
{
    
    cout<<"Real:";
    cin>>a;
    cout<<"Imagine:";
    cin>>b; 
}
void MyComplex::ConsoleOutput()
{
    if (b<0) cout<<a<<"-i"<<b;
    if (b==0) cout<<a;
    if (b>0) cout<<a<<"+i"<<b;
    cout<<endl; 
}
string MyComplex::Output()
{
    string s;
    return s;
}
MyComplex MyComplex::operator +(const MyComplex & r)
{
    return MyComplex(a+r.a,b+r.b);
}
MyComplex MyComplex::operator -(const MyComplex & r)
{
    return MyComplex(a-r.a,b-r.b);
}
MyComplex MyComplex::operator *(const MyComplex & r)
{
    return MyComplex(a*r.a-b*r.b,b*r.a+a*r.b);
}
MyComplex MyComplex::operator /(const MyComplex & r)
{
        r==0.0; // тут ошибка: Ошибка   1   error C2678: бинарный "==": не найден оператор, принимающий левый операнд типа "const MyComplex" (или приемлемое преобразование отсутствует)    d:\test\test\mycomplex.cpp  49  1   test
        if (r.a==0 && r.b==0) throw 1; 
        return MyComplex((a*r.a+b*r.b)/(pow(r.a,2)+pow(r.b,2)),(b*r.a-a*r.b)/(pow(r.a,2)+pow(r.b,2)));
}
bool MyComplex::operator==(double zero)
{
    return a==0 && b==0;
}
Добавлено через 2 минуты
И еще вопрос к try catch: Посоветуйте как правильно отловить ошибку с делением на 0.
C++
1
2
3
4
5
6
7
8
9
try
    {
            c=a/b;
            c.ConsoleOutput();
    }
    catch (int a)
    {
        cout<<"Error! Division by zero!"<<endl;
}
вот в мейне присутствует такой код, он работает. Так делать нормально?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.11.2011, 02:40     Перезагрузка operator ==
Посмотрите здесь:

Перезагрузка operator - C++
C++ operator <<
перезагрузка operator + C++
operator char() или operator int() C++
Перезагрузка операторов "неоднозначный operator" C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
13.11.2011, 08:18     Перезагрузка operator == #2
C++
1
bool operator==(double) const;
C++
1
2
3
4
bool MyComplex::operator==(double zero) const
{
        return a==0 && b==0;
}
Правда не совсем понятно, что это за оператор == такой, который тру возвращает, только если комплексное число нулевое... Но это на вашей совести остаётся.

Цитата Сообщение от Scorpion93 Посмотреть сообщение
Так делать нормально?
Да не особо...
Напишите свой класс-исключение, унаследованный от std::exception, и ловите ссылку на его объект.
Scorpion93
 Аватар для Scorpion93
2 / 2 / 0
Регистрация: 31.10.2010
Сообщений: 120
13.11.2011, 14:33  [ТС]     Перезагрузка operator == #3
Цитата Сообщение от silent_1991 Посмотреть сообщение
Напишите свой класс-исключение, унаследованный от std::exception, и ловите ссылку на его объект.
C++
1
2
3
4
5
6
7
#include <exception>
class MyExceptions:public std::exception
{
public:
    MyExceptions(void);
    ~MyExceptions(void);
};
подскажите пожалуйста: как добавить собственное исключение в этот клас?
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
13.11.2011, 14:34     Перезагрузка operator == #4
Цитата Сообщение от Scorpion93 Посмотреть сообщение
подскажите пожалуйста: как добавить собственное исключение в этот клас?
Этот класс и есть "исключение".
Scorpion93
 Аватар для Scorpion93
2 / 2 / 0
Регистрация: 31.10.2010
Сообщений: 120
13.11.2011, 16:17  [ТС]     Перезагрузка operator == #5
я понимаю, но как еще добавить исключения? скажем я делаю клас рациональная дробь и что бы в знаменателе не было 0. можно это без ifа и попыткой деления проверить?
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
13.11.2011, 16:45     Перезагрузка operator == #6
Scorpion93, таки непонятно, что именно вы хотите сделать? делаете класс рациональная дробь, добавляете свой класс исключения DivisionByZeroException, в методах класса рациональной дроби проверяете возможность возникновения ситуации деления на ноль и бросаете созданное исключение. В месте, откуда был вызван метод, отлавливаете это исключение и исправляетесь.
Scorpion93
 Аватар для Scorpion93
2 / 2 / 0
Регистрация: 31.10.2010
Сообщений: 120
13.11.2011, 20:06  [ТС]     Перезагрузка operator == #7
C++
1
2
3
4
5
6
7
8
9
void  MyRational::ConsoleInput()
{
    cout<<"Numerator: ";
    cin>>numerator;
    cout<<"Denumerator: ";
    cin>>denumerator;
    long temp=numerator/denumerator;
    
}
C++
1
2
3
4
5
6
7
8
try
    {
        a.ConsoleInput();
    }
    catch (exception& e)
    {
        cout << "Standard exception: " << e.what() << endl;
    }
программа не работает, выдает ошибку, но исключение не генерируется.. что за..?
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
14.11.2011, 08:49     Перезагрузка operator == #8
Scorpion93, так а где вы кидаете исключение-то? В методе ConsoleInput, по крайней мере, вы его не выкидываете.
Scorpion93
 Аватар для Scorpion93
2 / 2 / 0
Регистрация: 31.10.2010
Сообщений: 120
14.11.2011, 09:56  [ТС]     Перезагрузка operator == #9
C++
1
  long temp=numerator/denumerator;
denumerator равно 0... тоесть должно возникать исключение... или нужен if?
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
14.11.2011, 10:00     Перезагрузка operator == #10
Scorpion93, с чего бы оно должно возникать? Как программа узнает, что при делении на нуль нужно кидать пользовательское исключение? Это вам не дотнет, где за всем следит среда выполнения. Вы должны сами выбрасывать исключение в случае, если знаменатель равен нулю.
Bers
Заблокирован
14.11.2011, 10:05     Перезагрузка operator == #11
Исключения - неудачная практика, если их использовать не в исключительных ситуациях.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
14.11.2011, 14:15     Перезагрузка operator == #12
Bers, т.е. деление на нуль по-вашему - не исключительная ситуация?
Bers
Заблокирован
15.11.2011, 00:17     Перезагрузка operator == #13
Цитата Сообщение от silent_1991 Посмотреть сообщение
Bers, т.е. деление на нуль по-вашему - не исключительная ситуация?
Исключительная ситуация - это ситуация, спрогнозировать которую самостоятельно модуль не в состоянии.

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

Это нормальное положение вещей. Любой модуль должен быть готов к тому, что входные данные будут некорректными. И уметь корректно на это отреагировать. А не кидать в панике исключения, и не обрушивать весь процесс.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
15.11.2011, 12:54     Перезагрузка operator == #14

Не по теме:

Цитата Сообщение от Scorpion93 Посмотреть сообщение
перезагнрузкой оператора
Правильно говорить "пергрузка", а перезагружают комп.

А теперь вопрос, относящийся к теме: как ты хочешь хранить свои числа: в паре действительная/мнимая часть, или в паре модуль/угол? В первом случае числа равны, если их части попарно равны, во втором - если части равны после приведения обоих углов к одному диапазону, не превышающим в размахе 360 градусов (http://www.cyberforum.ru/cgi-bin/latex.cgi?2*\pi радиан, 400 градов, 1000 тысячных и т.п.), например, к диапазону от минус ста восьмидесяти до плюс ста восьмидесяти градусов, а можно от ноля до тёхсот шестидесяти, но оба.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
15.11.2011, 13:35     Перезагрузка operator == #15
Цитата Сообщение от Bers Посмотреть сообщение
не кидать в панике исключения,
Цитата Сообщение от Bers Посмотреть сообщение
и не обрушивать весь процесс
Эти две фразы не являются эквивалентными. Для того и нужны исключения, чтобы не крашить программу в рантайме.
Каким образом вы восстановитесь после ошибки "деление на нуль"? Возможно, пользователь имел ввиду 1? Окей, давайте вместо нуля единичку подставим. Стоп. А вдруг он хотел 10?..
Bers
Заблокирован
15.11.2011, 13:55     Перезагрузка operator == #16
Цитата Сообщение от silent_1991 Посмотреть сообщение
Эти две фразы не являются эквивалентными.
Тем не менее, это - нарушение инварианта класса. Если он бросит исключение, а вызывающая сторона его не обработает, класс окажется виновником крэша.

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

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


Цитата Сообщение от silent_1991 Посмотреть сообщение
Каким образом вы восстановитесь после ошибки "деление на нуль"?
Не нужно восстанавливаться после ошибки.
Нужно не допускать ошибок.
Нужно заранее спрогнозировать, что получится деление на ноль, и не допустить выполнение такой операции.

Если аргументы не_валидны (их использование приведёт к аварии), то - отказ всей операции. И откат на исходную позицию. Пользователь получает уведомление в виде кода ошибки (если это возможно), либо - любую дефолтную муру + GetLastError() если вернуть код ошибки средствами самого метода не возможно.

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

А релизе любой метод, который теоретически может сделать "отказ операции" нужно ВСЕГДА проверять на код ошибки. Конечно, если вызывающая сторона заинтересована в безопасности. Если не заинтересована - тогда не обязательно.

Она может игнорировать сообщения класса, и это не приведёт к крэшу, просто потому, что класс никогда не сделает ничего такого, что может привести к крушению.

Если же крэш происходит на территории вызывающей стороны (допустим класс не выполнил операцию, и вызывающая сторона оказалась неготовой к следующей операции, и эта следующая операция вызвала крэш) - то это уже косяк вызывающей стороны, и программиста, который её делал. Класс тут уже не приделах.

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



Цитата Сообщение от silent_1991 Посмотреть сообщение
Возможно, пользователь имел ввиду 1? Окей, давайте вместо нуля единичку подставим. Стоп. А вдруг он хотел 10?.
С точки зрения самого класса, как самостоятельной целостной логической единицы - совершенно не важно, о чем думала вызывающая сторона, когда присылала упоротые аргументы.
Важно только три вещи:

1. Не допустить крэша по своей вине.
2. Выполнить задачу, которую на класс навесил его создатель.
3. Выполнить штатную процедуру отказа от работы в случае, если выполнение работы противоречит первому пункту.

/зы исключение нарушает инкапсуляцию
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
15.11.2011, 14:11     Перезагрузка operator == #17
Bers,
Если все классы стремятся делать в духе строгой гарантии
Тогда бы не было других гарантий. Но они есть.

Ты слишком жестоко относишься к ислючениям.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
15.11.2011, 14:12     Перезагрузка operator == #18
Bers, чем деление на нуль отличается от выхода за границы массива?
Bers
Заблокирован
15.11.2011, 14:17     Перезагрузка operator == #19
Цитата Сообщение от ForEveR Посмотреть сообщение
Ты слишком жестоко относишься к ислючениям.
1. Они захламляют код, и ухудшают читабельность.
2. Нарушают инкапсуляцию класса.
3. Нарушают инвариант класса.

4. Идеологически - это последний рубеж обороны класса в борьбе за выживаемость системы.
Его следует использовать только тогда, когда очевидно, что класс своими силами не в состоянии справиться с возникшей проблемой, в надежде, что вызывающая сторона сумеет разрулить проблему.

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

Добавлено через 45 секунд
Цитата Сообщение от silent_1991 Посмотреть сообщение
Bers, чем деление на нуль отличается от выхода за границы массива?
Тем что деление на нуль - это деление на нуль.
А выход за пределы массива - это выход за пределы массива
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.11.2011, 14:24     Перезагрузка operator ==
Еще ссылки по теме:

C++ Expected init-declarator before "operator".expected `,' or `;' before "operator"
Operator = C++
Реализация operator + через operator += C++

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

Или воспользуйтесь поиском по форуму:
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
15.11.2011, 14:24     Перезагрузка operator == #20
Цитата Сообщение от Bers Посмотреть сообщение
Тем не менее, это - нарушение инварианта класса. Если он бросит исключение, а вызывающая сторона его не обработает, класс окажется виновником крэша.
Но если всё таки исключение необходимо, то придётся его бросить, иначе крах гарантированно будет до того, как кто то что то не обработает, а так хоть какая то надежда на продолжение работы. Но без нужды не кидать.
Yandex
Объявления
15.11.2011, 14:24     Перезагрузка operator ==
Закрытая тема Создать тему
Опции темы

Текущее время: 02:51. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru