Dashia18 / Simple_fraction_class

Class of simple fraction
0 stars 0 forks source link

sf+int or int+sf ? #6

Open Dashia18 opened 9 years ago

Dashia18 commented 9 years ago

Обсуждался вариант операций между простой дробью и double/int _sf_a + intc или _int_c+ sfa

Нужно ли это как-то реализовать еще. Либо шаблон я подумала и либо дружественную функцию тоже. Но пока что-то не придумала.

P.S. тебе вопросик @sergregory :8ball:

sergregory commented 9 years ago

В общем, я прочитал вот что: Если в классе есть конструктор преобразования (в нашем случае, из встроенных арифметических типов) - то есть такой конструктор, который принимает один аргумент и не объявлен с ключевым словом explicit (оно запрещает использовать конструктор для неявных преобразований), то достаточно перегрузить арифметические операторы (не являющиеся членами класса!) так, чтобы они принимали два операнда типа нашего класса. Тогда при использовании операций вида sf_a + sf_b будет вызываться просто такой оператор, а при использовании операций вида sf_a + int_b или int_a + sf_b будет конструироваться временный объект Simple_fraction и затем вызываться перегруженный оператор. В этом случае в классе перегружать операторы не надо.

Dashia18 commented 9 years ago

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

.h

Simple_fraction(int num);
friend Simple_fraction operator+ (const Simple_fraction& sf_a, const Simple_fraction& sf_b);

.cpp

Simple_fraction::Simple_fraction(int num){
    set_simple_fraction(num, 1);
}

main.cpp

 Simple_fraction sf_c;
sf_c= Simple_fraction(2);
std::cout<<"Summa  sf_a + sf_c ";
    sf_a + sf_c;
sergregory commented 9 years ago

Всё правильно, только теперь ещё должно работать сложение вот так:

int a = 2;
std::cout<<"Summa  a + sf_c = " << a + sf_c;
Dashia18 commented 9 years ago

Так, сделала вот такую штуку

.h

friend Simple_fraction operator+ (const Simple_fraction& sf_a, const Simple_fraction& sf_b);

friend Simple_fraction operator+ (const int& int_c, const Simple_fraction& sf_a){
        Simple_fraction sf_c = Simple_fraction(int_c);
        std::cout<<"Summa  int_c + sf_a ";
        Simple_fraction add_res = sf_c + sf_a;
        return add_res;
    };

friend Simple_fraction operatorator+ (const Simple_fraction& sf_a, const int& int_c){
        Simple_fraction sf_c = Simple_fraction(int_c);
        std::cout<<"Summa  sf_a + int_c ";
        Simple_fraction add_res = sf_a + sf_c;
        return add_res;
    };

Два дружественных перегруженных метода, которые принимают int и Simple_fraction, преобразует int в Simple_fraction и вызывает метод operator+ для двух Simple_fraction.

main.cpp

int_c+sf_a;
sergregory commented 9 years ago

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

Dashia18 commented 9 years ago

Ага, работает.

sergregory commented 9 years ago

Ура :) :+1:

Dashia18 commented 9 years ago

Ну и осталась еще одна вещь)

double operator+ (const double& double_d);
friend double operator+ (const double& double_d, const Simple_fraction& sf_a){ 
        Simple_fraction a = sf_a;
        double add_res = a + double_d;
        return add_res;
        //sf_a + double_d - не работает так вот, а как работает выше работает. не пойму почему
        };
sergregory commented 9 years ago

Если const убрать, будет работать? Вообще для double надо бы Simple_fraction переводить в double

Dashia18 commented 9 years ago

sf +double :

double Simple_fraction::operator+ (const double& double_d){
    double add_res;
    double sf_a = double(numerator)/double(denominatior);
    add_res = sf_a + double_d;
    std::cout<< add_res<<"\n\n";
    return add_res;
}

А то что вверху, я хотела double + sf .

Dashia18 commented 9 years ago

Без const почему-то работает.

double operator+ (const double& double_d);
friend void operator+ (const double& double_d, Simple_fraction& sf_a){ 
        sf_a + double_d;
        };
sergregory commented 9 years ago

Мне кажется будет правильно сделать так:

class Simple_fraction
{
...
    double operator+ (const double& double_d) const;
...
}

double operator+ (const double& double_d, const Simple_fraction& sf_a){ 
        return sf_a + double_d;
}
sergregory commented 9 years ago

У тебя оператор в классе объявлен без спецификатора const, а ссылка константная. К константным ссылкам нельзя применять неконстантные методы. Поскольку у тебя все арифметические операторы не меняют состояния объекта, то их все нужно объявить со спецификатором const

Dashia18 commented 9 years ago

Такая штука действует только для полей класса? Так как на этот метод не ругается

double operator+ (const double& double_d)

тут ведь тоже константная ссылка на double.

Dashia18 commented 9 years ago

Особо-то и не разрешает константные методы делать. Как сложно все. где-то можно, где-то нельзя констрантными делать, где-то даже нужно или не нужно. Вот так оставила.

//operator overloading (+,-,*,/) for sf+sf
    friend Simple_fraction operator+ (const Simple_fraction& sf_a, const Simple_fraction& sf_b);
    friend Simple_fraction operator- (const Simple_fraction& sf_a, const Simple_fraction& sf_b);
    friend Simple_fraction operator* (const Simple_fraction& sf_a, const Simple_fraction& sf_b);
    friend Simple_fraction operator/ (const Simple_fraction& sf_a, const Simple_fraction& sf_b);

    //operator overloading (+,-,*,/) for sf+double
    double operator+ (const double& double_d);
    double operator- (const double& double_d);
    double operator* (const double& double_d);
    double operator/ (const double& double_d);

    //operator overloading (+,-,*,/) for double+sf
    friend void operator+ (const double& double_d,  Simple_fraction& sf_a){sf_a + double_d;};
    friend void operator- (const double& double_d,  Simple_fraction& sf_a){sf_a - double_d;};
    friend void operator* (const double& double_d,  Simple_fraction& sf_a){sf_a * double_d;};
    friend void operator/ (const double& double_d,  Simple_fraction& sf_a){sf_a / double_d;};
sergregory commented 9 years ago

Ну можно считать что у встроенных типов константность расставлена правильно у методов, то есть где нужно - они константные.

sergregory commented 9 years ago

Не, давай константными сделаем арифметические операции, которые члены класса..

//operator overloading (+,-,*,/) for sf+sf
    friend Simple_fraction operator+ (const Simple_fraction& sf_a, const Simple_fraction& sf_b);
    friend Simple_fraction operator- (const Simple_fraction& sf_a, const Simple_fraction& sf_b);
    friend Simple_fraction operator* (const Simple_fraction& sf_a, const Simple_fraction& sf_b);
    friend Simple_fraction operator/ (const Simple_fraction& sf_a, const Simple_fraction& sf_b);

    //operator overloading (+,-,*,/) for sf+double
    double operator+ (const double& double_d) const;
    double operator- (const double& double_d) const;
    double operator* (const double& double_d) const;
    double operator/ (const double& double_d) const;

    //operator overloading (+,-,*,/) for double+sf
    friend void operator+ (const double& double_d, const Simple_fraction& sf_a){sf_a + double_d;};
    friend void operator- (const double& double_d, const Simple_fraction& sf_a){sf_a - double_d;};
    friend void operator* (const double& double_d, const Simple_fraction& sf_a){sf_a * double_d;};
    friend void operator/ (const double& double_d, const Simple_fraction& sf_a){sf_a / double_d;};
Dashia18 commented 9 years ago

Хорошо, добавила так. До этого ругался что там const, теперь нет. Не понимаю)