Przeciążanie operatorów

0

Na wstępie pragnę się z Wami przywitać, gdyż jestem tutaj nowy. Programować w C++ dopiero zaczynam, nigdy wcześniej z OOP nie miałem do czynienia. Przejdźmy do rzeczy:

Zadanie: Napisać .h oraz .cpp, umożliwiające poprawne uruchomienie poniższego kodu:

#include <iostream>
#include "portfel.h"

using namespace std;

int main()
{
Portfel p1(2300); //numer portfela nadawany automatycznie wg pola
//statycznego ile
Portfel p2(1800);
p1 + 100; //kwote w portfelu p1 zwiekszy o 100
p2 - 200; //kwote w portfelu p2 zmniejszy o 200
cout << p1 << p2 << endl; //wypisze pola prywatne portfeli p1 i p2
Portfel p3;
p3 = p1 + p2; //p3 jest suma portfeli p1 i p2 (suma bilansow z portfeli)
cout << p3 << endl;
return 0;
}

Oczywiście nie proszę Was o rozwiązanie, tylko o korektę moich błędów. Tyle udało mi się napisać:

portfel.h

 #ifndef portfel_h
#define portfel_h

#include <iostream>

using namespace std;

class Portfel {
    private:
        static int ile;
        int numer;
        float bilans;

    public:
        Portfel(); 
        Portfel(float);
        friend const Portfel operator+(const Portfel& left, const float right);
        friend const Portfel operator+(const Portfel& left, const Portfel& right);
        friend const Portfel operator-(const Portfel& left, const float right);
        friend const Portfel operator-(const Portfel& left, const Portfel& right);
        friend ostream& operator<<(ostream& os, const Portfel& right);
};

#endif

Pytania:

  1. Czytałem, że w tym pliku nie powinienem używać przestrzeni nazw, gdyż wszędzie gdzie dołączę tą bibliotekę, odsłonię przestrzeń std. W takim razie w jaki sposób powinienem napisać ten plik, żeby móc go skompilować?

portfel.cpp

#include <iostream>
#include "portfel.h"

using namespace std;

int Portfel::ile = 0;

Portfel::Portfel() {
    ile++;
    numer = ile;
    bilans = 0.0;
}

Portfel::Portfel(float p) {
    ile++;
    numer = ile;
    bilans = p;
}

const Portfel operator+(const Portfel& left, const float right) {
    return Portfel(left.bilans + right);
}

const Portfel operator+(const Portfel& left, const Portfel& right) {
	return Portfel(left.bilans + right.bilans);
}

const Portfel operator-(const Portfel& left, const float right) {
    return Portfel(left.bilans - right);
}

const Portfel operator-(const Portfel& left, const Portfel& right) {
	return Portfel(left.bilans - right.bilans);
}

ostream& operator<<(ostream& os, const Portfel& right) {
    os << "Numer konta: " << right.numer
       //<< "\nIle: " << right.ile
       << "\nBilans: " << right.bilans << endl;
}
 

Pytania:

  1. Przeciążając operatory (np. +) i uruchamiając program nie dzieje się nic - wartość nie jest zwiększona. Domyślam się, że jest to powodowane tym, że działam na kopii nie modyfikując pól prywatnych klasy. Jak to zmienić?
  2. Problem z pytania pierwszego generuje mi kolejną niespójność - zmienna statyczna ile inkrementuje się podczas tworzenia kopii (być może moje założenie jest złe) i numer portfela p3 osiąga wartość 6 - zamiast 3.
  3. Nie mogę wyświetlić zmiennej statycznej ile - dlatego zakomentowałem. Wiem, że nie powinienem się odwoływać do niej w sposób: right.ile tylko po prostu ile, jednak wtedy nie mogę skompilować projektu.
  4. O tym jak przeciążać operatory czytałem w książce Eckela, jednak wiem, że kod powinien u mnie wyglądać nieco inaczej... chodzi mi o to, że widziałem również zapis:
    Portfel Portfel::operator+ //coś w tym stylu, nie zdążyłem zanotować. Jak tego użyć?

Domyślam się, że to co piszę jest banalne... głupio mi zawracać Wam głowę takimi podstawami, jednak męczę się z tym już dłuższą chwilę i nic nie przychodzi mi do głowy.

@Edit: Teraz zauważyłem, że pytanie powinienem umieścić w dziale Newbie. Jeśli to konieczne to proszę moderatora o przeniesienie mojego tematu.

Pozdrawiam serdecznie

1

Przecież takie coś: p1 + 100; zasadniczo nie ma sensu. Nic nie robisz z wynikiem tej operacji, albo powinno być p1 = p1 + 100 albo p1 += 100 ale to inny operator. Same operatory są w sumie dobrze (const w typie zwracanym oraz przy float są niepotrzebne).

ile jest składnikiem statycznym, odwołujesz się do niego przez Portfel::ile. Jeżeli chcesz liczyć ilość obiektów musisz zaimplementować dodatkowo konstruktor kopiujący oraz destruktor i odpowiednio dodawać/odejmować od obecnej liczby obiektów. (Nie jestem pewien co chcesz osiągnąć)

W nagłówku nie dawaj using namespace, wszystko co trzeba poprzedzaj std:: (w sumie tylko std::ostream). Nie musisz też dołączać <iostream>, <iosfwd> wystarczy.

0

Ad 1a. std::ostream zamiast ostream
Ad 1b. bo opierator const Portfel operator+(const Portfel& left, const float right) powinien wyglądać void operator+(Portfel& left, const float right) i działać jak += owszem nie jest to dobra praktyka ale tak jest w zadaniu.
Ad 2. Portfel(float p,bool Czy_Zwiekszyc_Pole_Statyczne=flase);
Ad 3. Przecież nawet tego użyłeś: Portfel::ile, zresztą right.ile też może być, poczytaj uważnie komunikat pewnie dotyczy czegoś innego.
Ad 4. Niektóre można przeciążyć jako metody wtedy pierwszy operand to this zaś drugi (o ile jest) to parametr metody (nie potrzebujesz friend, bo to metoda).

0

Dzięki Panowie za odpowiedzi. Operator "+" rzeczywiście należało przeciążyć tak, jak "+=". Potrzebny był jeszcze konstruktor kopiujący oraz destruktor. Postaram się już nie zadawać tego typu pytań...:) Temat można zamknąć.

Pozdrawiam

0
wymyslony_nick napisał(a):

Potrzebny był jeszcze konstruktor kopiujący oraz destruktor.
Absolutnie nie potrzebny, chyba że masz coś więcej w klasie niż pokazałeś.

1 użytkowników online, w tym zalogowanych: 0, gości: 1