Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Co lepiej zwracać operatorem '+' przy klasie?

Ostatnio zmodyfikowano 2017-01-07 01:48
Autor Wiadomość
latajacaryba
Temat założony przez niniejszego użytkownika
» 2017-01-05 12:42:47
Type Type::operator+(const Type& lhs)
{
Return Type wynik(this->skladnik+ lhs.skladnik)
}
Tak jest dobrze?
zwracamy obiekt w ktroego konstruktorze jest wartosc sumy skladnikow this i lhs?
Bo poprzednio this bylo modyfikowane (tak byc nie powinno)
P-156019
pekfos
» 2017-01-05 18:45:00
A może by tak więcej zastanowienia wkładać w już udzielone odpowiedzi, jak i własne? Zamiast zgadywać i podawać kod z głupimi błędami, przeanalizuj, i tak już wystarczające odpowiedzi, i wtedy napisz rozsądną odpowiedź. To nie rozmowa IRL, tu nie musisz płynnie udzielać odpowiedzi, więc poświęć te 2 minuty na sprawdzenie, czy to co piszesz ma ręce i nogi.
P-156044
latajacaryba
Temat założony przez niniejszego użytkownika
» 2017-01-06 01:34:17
Dobra, teraz porządnie się zastanowiłem.
Jeśli coś jest źle, to wynika to z mojej niewiedzy a nie niedopatrzenia.
C/C++
#include <iostream>
using namespace std;
class Type
{
public:
    // zmienne
    int a;
    double b;
   
    // nie wazne:
    void info()
    {
        cout << "a = " << a << endl << "b = " << b << endl << endl;
    }
    Type( int aa, double bb )
        : a( aa )
         , b( bb )
    { };
    // wazne ponizej:
   
   
    Type & operator +=( const Type & obj2 ) // 1)
    {
        a += obj2.a;
        b += obj2.b;
        return * this; // 2) zwracamy referencję
    }
   
};
Type operator +( Type obj1, const Type & obj2 )
{
    obj1 += obj2;
    return obj1;
}
int main()
{
    Type obj1( 2, 3.5 );
    Type obj2( 4, 1.5 );
    ( obj1 + obj2 ).info();
    obj1.info();
    obj2.info();
}
Kod do ctrl+c ctrl+v, kompiluje sie i wychodzi na to, że dziala.
Mam wątpliwości tylko do tego co się dzieje przy obj1+= obj2 w operatorze +. Po kolei: OPERATOR+ : obiekt obj1 jest przekazywany przez kopie, a drugi obj2 przez stałą referencję.
Następnie wywoływany jest operator += . Jako argumenty przyjmuje obj1 przez referencje - i teraz pytanie:
        += jest wywoływane na rzecz objektu obj1 (bo jest po l-wartością), ale ten objekt jest tylko kopią. Potem zmodyfikowaną kopie zwracamy w 3) przez referencje. Czy tak można?
Jesli tak, to wszystko sie zgadza. Tak więc: wywolywany jest op. +, a w nim += . operator += dodaje nam wartości objektów i zwraca tę nieszczęsną referencje *this (czyli obj1 bo to na jego rzeczy bylo wywolane +=).
Na koniec (w operatorze +) zwracana jest kopia obj1(już zmodyfikowanego przez operator+=).
Jedyne do czego się nie zastosowałem to uwaga Pekfosa, że operator += powinien być const. Po co? ma zwracać stałą referencję? Bo na pewno operator += modyfikuje obiekt...
P-156081
michal11
» 2017-01-06 08:51:06
Ogólnie dobrze myślisz. Z tego co zrozumiałem to pekfos mówił o innym przypadku niż ty masz, kiedy zamiast pierwszego arg. do operatora+ przekazujesz referencje a nie kopię, wtedy to powinna być const referencja, żeby można było przesyłać też r-wartości. Ogólnie operator+ mógłby tez wyglądać tak

C/C++
Type operator +( const Type & lhs, const type & rhs )
{
    Type ret;
    ret.a = lhs.a + rhs.a;
    ret.b = lhs.b + rhs.b;
    //...
    return ret;
}

i to tez byłoby ok. Pomysł aby przekazywać pierwszy arg. przez kopię jest na cppreference i tam możesz też przeczytać uzasadnienie dlaczego tak jest a nie inaczej. Swoją drogą ja raczej dotychczas pisałem operator+ (i inne z tej rodziny) albo jako normalną metodę albo właśnie z const referencją.
P-156082
latajacaryba
Temat założony przez niniejszego użytkownika
» 2017-01-06 12:47:38
Dobra, już zrozumiałem :)
Wielkie dzięki za pomoc Michał i Pekfos, przepraszam również za trochę nieprzemyślane kody, postaram się takowych już nie pisać.
Jeszcze raz dzięki i temat zamykam.
P-156083
latajacaryba
Temat założony przez niniejszego użytkownika
» 2017-01-06 17:56:24
Temat otwieram, bo nie dopytałem o operator, na rzecz którego właściwie założyłem ten temat :D. Spokojnie, będzie krótko:
class Typ
int a;
double b;
string opis;
operator+(int x);

Co powinien zwracać taki operator? Od razu zawiadamiam, że będzie on wykonywał tylko to: this->a+x;
Jestem za tym, by zwracał kopie obiektu, bo nawet kiedy będziemy chcieli zrobic tak:
Typ obj1;
obj.a = 5;
int liczba = obj+5;

To po prostu stworzymy sobie operator konwertujący objekt klasy Typ->int (typ na int), np.
operator int()
{
    return rzeczywista;
}

Co Wy o tym myślicie?
Bo o ile łatwo jest zrobic taki operator:
C/C++
Zlozona operator +( Zlozona obj, int a )
{
    obj.rzeczywista += a;
    return( a );
}
To jak zrobic taki operator jako funkcję składową bez tworzenia nowego obiektu w jej ciele? Powiedzmy, że klasa Zlozona ma wiele tablic itp, no i tworzenie nowego obiektu w ciele operatora nie wchodzi w gre. Co wtedy?
P-156116
czaffik
» 2017-01-06 18:42:05
No jak ci do czegoś potrzebny taki operator to możesz go sobie utworzyć, może zwracać kopię obiektu, może nie zwracać nic, ale jak chcesz korzystać z takiego zapisu:
C/C++
c = b + 2;
to niech zwraca kopię obiektu, bo oryginalnego obiektu to działanie nie zmodyfikuje, może też zwracać referencję, ale wtedy warto ją zabezpieczyć w const, bo możesz do wyniku przypisać wskaźnik, zmodyfikować wskaźnik i tym samym oryginalny obiekt i będzie zonk.
Możesz tworzyć operatory jak chcesz, niekoniecznie muszą być związane z operacjami matematycznymi, ale wiadomo że jednak taki operator coś reprezentuje i warto trzymać się pewnych reguł żeby to było sensowne.
"Zlozona ma wiele tablic itp, no i tworzenie nowego obiektu w ciele operatora nie wchodzi w gre" - to jak ci zależy na szybkości działania to najlepiej chyba przyjmować przez const referencję i zwracać const referencję.
P-156120
latajacaryba
Temat założony przez niniejszego użytkownika
» 2017-01-06 18:58:55
To ma być funkcja składowa, jaki Ty obiekt chcesz przyjmować? :/
No dobra, ale jak chcesz zrobić operator +(int) jako funkcję składową?
C/C++
class Type
{
    int a;
    double tab[ 10 ];
    int * dynamicznie;
    (...) operator +( int x );
};
Co taki operator powinien zwracać?
Na pewno nie może modyfikować obiektu na który wskazuje this.
Ale z drugiej strony nie chce tworzyć nowego obiektu i go zwracać (taki obiekt musiałby być utworzony na wzór tego na który wskazuje this, a on ma już jakieś wartości w tablicach, jakieś utworzone dynamicznie zmienne/tablice itp.)

Tak więc jak?
P-156121
1 « 2 » 3
Poprzednia strona Strona 2 z 3 Następna strona