Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[C++] Konstruktory, metody, operatory.

toma5z 05 Lut 2010 16:36 2814 4
  • #1 05 Lut 2010 16:36
    toma5z
    Poziom 13  

    Witam,
    mam problem z zadaniem:

    Cytat:
    Zdeklaruj klase ułamek, zawierające pola prywatne: licznik i mianownik, oraz składowe publiczne: konstruktor bezargumentowy, konstruktor kopiujący i bezargumentową metodę wczytaj.
    Dla powyższej klasy zdeklaruj i zdefiniuj operator+ dodawania dwóch ułamków


    Moja propozycja to:
    Code:

    class ulamek
    {
        private:
        double licznik;
        double mianownik;
       
        public:
        ulamek();  //konstruktor bezargumntoy
       
        ulamek::ulamek(ulamek& kopia_ulamek)
       {
                licznik=kopia_ulamek.licznik;
                mianownik=kopia_ulamek.mianownik;
          //konstruktor kopiujący
       }
       
        void wczytaj(); //metoda bezargumentowa

          
    };

       //operator+
    ulamek ulamek::operator+(int suma)
    {
       licznik+mianownik=suma;
       return (suma);
    }


    Czy to było by coś takiego ?
    Proszę o pomoc.

    0 4
  • #2 05 Lut 2010 18:24
    Dariusz Bismor
    Poziom 17  

    Absolutnie NIE. Po pierwsze, nawet gdy metody są bezargumentowe, muszą mieć ciało. Konstruktor, można się domyślić, ustawi licznik na zero, mianownik na coś różnego od zera. Trudno zgadnąć, co ma robić metoda wczytaj(), więc chyba kod pusty.
    Ale najbardziej źle napisaną masz funkcję operatorową. Po pierwsze, metody "operator+()" nie masz w definicji klasy ulamek. Poza tym, widziałeś kiedyś, by jak wykonujesz dodawanie: 1/2 + 3/4, to wynik był ładowany do 3/4? Ponadto Twój kod na dodawanie ułamków posługuje się zupełnie inną matematyką, niż ta, którą powszechnie uczy się w szkołach. Widziałeś gdzieś, by dodawać licznik do mianownika?
    Zazwyczaj przyjmuje się, że operatory, które nie zmieniają stanu klasy będącej ich argumentem definiuje się jako funkcje globalne. Zatem operatory +, -, *, /, % powinny być funkcjami globalnymi. Z kolei operatory +=, -=, *=, itd zazwyczaj definiuje się jako funkcje składowe. Ponieważ operator + zapisany jako funkcja składowa musi mieć dostęp do składników prytwantych klasy ulamek (nie masz funkcji udostępniających), musisz zadeklarować przyjaźń klasy ulamek do funkcji operatora. Sam operator może wyglądać tak:

    Code:
    ulamek operator+(const ulamek &s1, const ulamek &s2){
    
      ulamek suma;
      suma.mianownik = s1.mianownik * s2.mianownik;
      suma.licznik = s1.licznik*s2.mianownik + s1.mianownik*s2.licznik;
      return suma;
    }


    HTH,
    Dariusz

    0
  • #3 05 Lut 2010 19:28
    toma5z
    Poziom 13  

    czyli w taki sposób ?

    Code:

    class ulamek
    {
        private:
        double licznik;
        double mianownik;
       
        public:
        ulamek()  //konstruktor bezargumntoy
        {
               this->licznik = 0;
          this->mianownik != 0;

         }

        ulamek::ulamek(ulamek& kopia_ulamek)
        {
                licznik=kopia_ulamek.licznik;
                mianownik=kopia_ulamek.mianownik;
          //konstruktor kopiujący
        }
       
        void wczytaj()
         {
            cin>>licznik>>mianownik; //nie mam pojęcia co tu ma się dziać ?
                           
         }
     //metoda bezargumentowa

         ulamek& operator+(ulamek & a)
       {
       ulamek *ul = new ulamek;

       u1->licznik = (licznik*a.mianownik)+(a.licznik*mianownik);
       u1->mianownik = mianownik * a.mianownik;

       return *ul;
       }
           // operator+ dodawania coś w tym stylu ?
    };

    0
  • #4 31 Paź 2014 14:07
    ShinsPL
    Poziom 13  

    Wyrażenie

    Kod: cpp
    Zaloguj się, aby zobaczyć kod
    jest porównaniem, a nie przypisaniem (dokładnie przeczytałbym to: jeśli lewa strona jest różna od prawej).

    Do mianownika możesz przypisać dowolną wartość niezerową korzystając tylko z "=" a nie z "!=".

    0
  • #5 31 Paź 2014 15:55
    mcvsama
    Poziom 15  

    Dodam, że skoro konstruktor kopiujący nie zamierza modyfikować źródła (a raczej zwykle nie powinien), to lepiej napisać z constem - wtedy będziesz mógł też kopiować z ulamków, które są const.

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    W Twoim nowym kodzie operator+ zwraca referencję do nowo zaalokowanego obiektu, którego potem i tak nikt nie skasuje, bo kto by się spodziewał, że należy to zrobić? I przez to masz wyciek pamięci. Zwróć ulamek, nie ulamek&. Nie twórz obiektu na stercie za pomocą new, tylko po prostu swórz zmienną typu ulamek. W ogóle unikaj new i delete, raczej używaj smart-pointerów.

    Acha - tak samo jak w konstruktorze kopiującym, niech operator+ pobiera stałą referencję "ulamek const&", a nie "ulamek&".

    Dalej - w klasie nie musisz pisać ulamek::ulamek(…), wystarczy ulamek(…). Dopiero jeśli definiujesz metodę poza klasą, musisz pisać pełną nazwę ulamek::ulamek(…), żeby było wiadomo o jakiej klasie mówisz i o jakiej metodzie w tej klasie mówisz.

    Natomiast metoda wczytaj() zapewne faktycznie miała „wczytać” dane od użytkownika… Ale uniwersalna klasa taka jak ten ulamek nie powinna zajmować się pobieraniem danych od użytkownika. Jej istotą powinno być operowanie na ułamkach, a nie implementowanie interfejsu użytkownika programu. No ale to już bardziej przytyk do tej osoby, która sformułowała zadanie; zresztą nie jest napisane co ma robić wczytaj, więc równie dobrze może nic nie robić, tak jak napisał Dariusz. ;-)

    Tak swoją drogą - metody nie muszą mieć ciała, jeśli nigdy nie zamierzasz ich wywoływać (są takie meta-triki czasem, w których używa się metod, których tak naprawdę nigdy się nie wywołuje). Ale oczywiście w tym programie jak najbardziej ciała są potrzebne.

    0