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

Przeciążenie operatorów - zasada działania

Ostatnio zmodyfikowano 2014-11-11 01:13
Autor Wiadomość
Atexor
Temat założony przez niniejszego użytkownika
Przeciążenie operatorów - zasada działania
» 2014-11-10 15:04:24
Witam, uczę się przeciążenia operatorów i 2 problemy.

Otóż chcę uzyskać nowy wektor (o takiej budowie: 3 1 5 10 8 - tzn. nie wektor z matematycznej definicji) poprzez przemnożenie już 2 istniejących lub 1 istniejącego przez liczbę (skalar).
Mam takie 2 przypadki:

Plik main:
C/C++
wektor wek_3 = wek_1 * wek_2; //przypadek 1
wektor wek_4 = wek_3 * liczba; //przypadek 2

W pliku nagłówkowym klasy "wektor":
C/C++
void mnoz( const wektor & b );
static wektor mnoz_2_wektory( const wektor & a, const wektor & b );
static wektor mnoz_przez_liczbe( const wektor & a, double liczba );
wektor operator *( const wektor & b );

Zaś w .cpp:
C/C++
void wektor::mnoz( const wektor & b )
{
    assert( this->ilosc == b.ilosc );
    for( uint32_t i = 0; i < this->ilosc; i++ )
    {
        this->wartosci_tab[ i ] *= b.wartosci_tab[ i ];
    }
}

wektor wektor::mnoz_2_wektory( const wektor & a, const wektor & b )
{
    //assert(a.ilosc == b.ilosc);
    wektor wek_wynik( a.ilosc );
   
    for( uint32_t i = 0; i < a.ilosc; i++ )
    {
        wek_wynik.wartosci_tab[ i ] = a.wartosci_tab[ i ] * b.wartosci_tab[ i ];
    }
   
    return wektor( wek_wynik );
}

wektor wektor::mnoz_przez_liczbe( const wektor & a, double liczba )
{
    wektor wek_wynik( a.ilosc );
    wektor::liczba = liczba;
    for( uint32_t i = 0; i < a.ilosc; i++ )
    {
        wek_wynik.wartosci_tab[ i ] = a.wartosci_tab[ i ] * liczba;
        std::cout << wek_wynik.wartosci_tab[ i ] << " " << endl;
    }
    return wektor( wek_wynik );
}


wektor wektor::operator *( const wektor & b )
{
    this->mnoz( b );
    return * this;
}

I tutaj mam 2 problemy (przypadki):
1. Nie wiem czemu DZIAŁA mi mnożenie 2 wektorów. Powyższy zapis w main.cpp jest po to, aby korzystał z operatora mnożenia, który zaś wywołuje:
void wektor::mnoz( const wektor & b );

Początkowo metoda "mnoz" miała służyć do mnożenia wektora przez siebie, jednak jak się okazuje również działa w przypadku mnożenia 2 wektorów i przekazania ich iloczynu do trzeciego, nowego wektora.

Tak więc jakim prawem to działa, skoro
this->wartosci_tab[ i ]
to tablica z NOWEJ instancji klasy wektor (wek_3) i metoda przyjmuje tylko 1 wektor "b"? Brakuje mi drugiego wektora do mnożenia...
Gdy próbowałem użyć:
this->mnoz_2_wektory zamiast this->mnoz
 (w operatorze) to miałem problemy (brak inicjalizacji, bo metoda ma mieć 2 argumenty). Tak samo z przekazaniem 2 argumentów do operatora, który przyjmuje tylko 1.

Dokładnie tak samo mam z analogicznymi metodami dodawania: metoda z 1 argumentem "dodaj" miała dodawać do siebie wektor, a działa w przypadku 2 dodawania różnych wektorów i zapisania ich wyniku w trzecim.

2. W powyższej formie (wektor wek_4 = wek_3 * liczba) chciałbym mieć mnożenie przez liczbę, które nie działa.
Mnożenie mam mieć pośrednio z użyciem operatora, a nie odwołując się w main do konkretnej metody konkretnej instancji klasy wektor.

Jak mam to zrobić, aby w zależności czy zrobię tak:
wektor wek_3 = wek_1 * wek_2;
czy tak:
wektor wek_4 = wek_3 * liczba;
gdzie drugi czynnik to raz liczba, raz wektor robiło mi odpowiednie obliczenia (metody) z wykorzystaniem operatora?


Bardzo prosiłbym o pomoc w tych kwestiach.
Pozdrawiam
P-120296
akwes
» 2014-11-10 15:05:18
Zacznijmy od poprawy tematu :)
P-120297
Atexor
Temat założony przez niniejszego użytkownika
» 2014-11-10 15:07:17
Już poprawiłem, w chwili wysłania zauważyłem, że zapomniałem o tym :)
P-120298
Monika90
» 2014-11-10 15:42:33
C/C++
wektor wektor::operator *( const wektor & b )
{
    this->mnoz( b );
    return * this;
}
Powyższy operator mnoży wektor *this przez wektor b, a następnie zwraca kopię wektora *this

Najlepiej zmień podejście na typowo stosowane. Tzn. definujesz operatory += *= itp. jako składowe klasy, a operatory + - * / jako zewnętrzne funkcje (które nawet nie muszą mieć dostepu do prywatnych składników klasy) i które są zaimplemetnowane za pomocą *= += /=
P-120303
Atexor
Temat założony przez niniejszego użytkownika
» 2014-11-10 16:13:21
Powyższy operator mnoży wektor *this przez wektor b, a następnie zwraca kopię wektora *this

Z tego co rozumiem tow wypadku:
wektor wek_3 = wek_1 * wek_2;

wskaźnik *this wskazuje na instancję klasy, dla której został wywołany, czyli tu this wskazuje na wek_3.

Następnie metoda mnoz(b) dostaje 1 argument, np. wek_1. W takim razie gdzie się podziewa wek_2?

Z operatora += korzystam do dodania w 1 miejscu wektora pierwszego do drugiego - gdy wektor drugi już istnieje i ma wartości. A powyżej chodziło o dodanie do już nowego.

wektor wek_2(wek_1); //korzystam z konstruktora kopiującego
wek_2 += wek_1;.

Teraz dzięki Tobie widzę że narodził się jeszcze jeden problem, bo przed użyciem powyższego zapisu mam:
wektor wek_4 = wek_1 + wek_2;
i mimo, że tworzy poprawnie wek_4, to również zwiększa wartość wektora wek_1 (jak w sumie zamienię kolejność to wtedy wek_2).



Zaś do podejścia typowo stosowanego:
Nie rozumiem o co Ci chodzi z zaimplementowaniem operatorów + - * / przy użyciu *= += /=

Mam "zagnieździć" zewnętrzne operatory w operatorach klasy?
Mogłabyś to bardziej wyjaśnić, tym bardziej że ten temat jest dla mnie pojęciem "z lekka" abstrakcyjnym?
P-120308
Monika90
» 2014-11-10 16:17:30
Z tego co rozumiem tow wypadku:
wektor wek_3 = wek_1 * wek_2;

wskaźnik *this wskazuje na instancję klasy, dla której został wywołany, czyli tu this wskazuje na wek_3.
operator * jest wywołany dla wek_1, więc w tym operatorze this wskazuje na wek_1
P-120309
Atexor
Temat założony przez niniejszego użytkownika
» 2014-11-10 20:07:03
Próbuję naprawić ten program, ale nadal nie wiem jak to naprawić.

Chcę utworzyć nowy wektor, który jest sumą 2 poprzednich:
wektor wek_3 = wek_1 + wek_2;
Te działanie korzysta z tego operatora:
C/C++
wektor wektor::operator +( const wektor & b )
{
    this->dodaj( b );
    return * this;
}

Czyli zgodnie z tym wywołuje dodawanie dla wek_1 i koniec końców mam wektor nr 3 poprawny, ale też wektor nr 1 zwiększony. Próbowałem usunąć wskaźnik this i inne rzeczy, aby te dodawanie było dla wektora 3, ale bezskutecznie.

Dlatego też potem
cpp]wek_2 += wek_1;[/cpp]
nie działa poprawnie, bo mimo że robi to co powinno, na "niepożądanie zwiększonym wektorze 2".
C/C++
void wektor::operator +=( const wektor & b )
{
    this->dodaj( b );
}

I dalej te nieszczęsne rozpoznanie co ma robić: mnożenie 2 wektorów czy wektora i liczba.
P-120336
Monika90
» 2014-11-10 20:21:20
Utwórz kopię *this, dodaj do niej i zwróć ją.
C/C++
wektor wektor::operator +( const wektor & b )
{
    wektor w( * this );
    w.dodaj( b );
    return w;
}
P-120337
« 1 » 2
  Strona 1 z 2 Następna strona