• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Dwie klasy w programie obiektowym

Object Storage Arubacloud
0 głosów
423 wizyt
pytanie zadane 26 października 2016 w C i C++ przez Evelek Nałogowiec (28,960 p.)

Mój kod programu wygląda tak:

#include <iostream>
#include <cmath>
using namespace std;

class Potworek
{
private:
    std::string name_;
    int sila_uderzenia_;
public:
    int sila_obrony_;
    int hp_;
    void atakowanie();
};

class Bohater
{
private:
    std::string name_;
    int sila_uderzenia_;
public:
    int hp_;
    int sila_obrony_;
    void atakowanie();
};

void Potworek::atakowanie()
{
    Bohater::hp_ = Bohater::hp_ - abs(sila_uderzenia_ - Bohater::sila_obrony_);
}

Jeszcze nie doszedłem do tego jak to zrobić, ale chciałbym wiedzieć już teraz. W jaki sposób odwoływać się do zmiennych klasy Bohater w metodach klasy Potworek? W obecnym stanie programu mam błędy:

  • invalid use of non-static data member 'Bohater::hp_'|
  • invalid use of non-static data member 'Bohater::hp_'|
  • invalid use of non-static data member 'Bohater::sika_obrony_'|

Czyli źle się odwołuje. Jaka jest poprawna składania i jak to się nazywa w programowaniu obiektowym? smiley

1 odpowiedź

0 głosów
odpowiedź 26 października 2016 przez zperkowski Stary wyjadacz (11,150 p.)
wybrane 26 października 2016 przez Evelek
 
Najlepsza
Operator :: dotyczy przestrzeni nazw. Operator dostępu do klasy to znak kropki. Spróbuj Bohater.hp. Itd.
komentarz 26 października 2016 przez Evelek Nałogowiec (28,960 p.)

Super. Pomogło. Tym razem mam taki błąd i nie mogę się dopatrzeć czego brakuje:

  • expected unqualified-id before '.' token

W linijce: 

Bohater.hp_ = Bohater.hp_ - abs(sila_uderzenia_ - Bohater.sila_obrony_);

 

komentarz 26 października 2016 przez zperkowski Stary wyjadacz (11,150 p.)
W ogóle po spojrzeniu na Twój kod to powinieneś się jeszcze pouczyć na temat obiektowego programowania. void Potworek::atakowanie() jest niepoprawne, ponieważ znajduje się poza ciałem klasy. Do tego nie wywołuje się metod klasy względem atrybutów innej klasy. Wywołuje się metody względem obiektów.

W kursie Pasja Informatyki C++ Obiektowy jest wszystko wyjaśnione.
komentarz 26 października 2016 przez Evelek Nałogowiec (28,960 p.)

Tyle, że mi chodziło o ten konkretny przykład w jaki sposób to można osiągnąć...

void Potworek::atakowanie() znajduje się poza ciałem klasy - dlaczego uważasz to za błąd? Przecież definicje metod można umieszczać poza klasą poprzez operator zasięgu ::.

Super, że odwołujesz mnie do kursu Pasja Informatyki. Oglądałem go już kilkanaście razy. Ale powtórzę, że chciałbym osiągnąć to o czym piszę w ten konkretny sposób. Jeśli nie ma takiej możliwości to napisz, wtedy będę rozwiązywał problem inaczej, np. tak jak napisałeś: "Wywołuje się metody względem obiektów.". Tym bardziej, że nie piszę programu z podziałem na pliki nagłówkowe, pliki z funkcjami klasy itd. tylko w celach edukacyjnych wszystko w jednym, aby sprawdzić, czy daną rzecz mogę osiągnąć w wybrany przez siebie sposób tak jak w tym przypadku.

2
komentarz 26 października 2016 przez zperkowski Stary wyjadacz (11,150 p.)

Ponieważ atakujesz ogólnym schematem potwora ogólny schemat bohatera. Żaden konkretny potwór nie atakuje żadnego konkretnego bohatera.

#include <iostream>
#include <cmath>

using namespace std;

class Bohater {
private:
    std::string name_;
    int sila_uderzenia_;
public:
    int hp_;
    int sila_obrony_;

//    void atakowanie();
};

class Potworek {
private:
    std::string name_;
    int sila_uderzenia_;
public:
    int sila_obrony_;
    int hp_;

    virtual void atakowanie(Bohater *boh);
};


void Potworek::atakowanie(Bohater *boh) {
    boh->hp_ = boh->hp_ - abs(sila_uderzenia_ - boh->sila_obrony_);
}

Nie wiem o ten efekt Ci chodzi, ale przykład dałeś taki, że inaczej się nie da pod względem logiki. Żeby bezpośrednio się odwoływać do atrybutów klasy, a nie obiektu to klasa powinna mieć atrybuty statyczne, czyli identyczne dla każdego obiektu tej klasy, co powoduje sytuacje, że każdy bohater otrzymuje obrażenia, nie ważne który jest atakowany.

Tak w ogóle używasz using namespace std, ale przy stringu i tak dodajesz przestrzeń nazw std::.

3
komentarz 26 października 2016 przez plkpiotr Stary wyjadacz (12,420 p.)

Dokładnie, tak jak pisze zperkowski. Dobrze, że dodał argument na którym możemy dokonywać modyfikacji - na rzecz którego wykonywana jest funkcja. Na obecną chwilę możesz zastosować taki skrót logiczny w przypadku twojego programiku:
Operator zasięgu :: używamy na rzecz klasy, czyli na przykład odnosisz się do metody z danej klasy, wskazujesz, że metoda lub np. typ wyliczeniowy z niej pochodzi. Natomiast kropka . służy do wywoływania tej metody na rzecz danego obiektu lub "dostania się" do jego pola składowego.

Chodzi tu o rozróżnienie pomiędzy klasą (reprezentacją cech), a obiektem (przedstawicielem klasy).

1
komentarz 26 października 2016 przez criss Mędrzec (172,590 p.)

Operator :: dotyczy przestrzeni nazw. Operator dostępu do klasy to znak kropki. 

Operator :: jest operatorem zasięgu za pomocą którego możesz dostać (dać znać, że to po prawej nalezy do tego po lewej) do pól/funkcji/metod/obiektów/czegokolwiek wewnątrz namespace-u/struktury/klasy/unii. Jednak, to czy ma to jakiś sens już leży po twojej stronie. Np. w twoim przypadku Bohater::hp_ nie ma żadnego.

Kropka umożliwia dostanie się do pola konkretnego obiektu. 

void Potworek::atakowanie() jest niepoprawne, ponieważ znajduje się poza ciałem klasy.

Przecież sam to zrobiłeś w swoim kodzie. Oczywiście, że jest poprawne. Nawet z reguły w C++ definiuje sie metody poza definicją klasy.

  atrybuty statyczne, czyli identyczne dla każdego obiektu tej klasy,

Nawet nie tyle identyczne, co po prostu statyczne pola są wspólne dla wszystkich obiektów.

 Tak w ogóle używasz using namespace std, ale przy stringu i tak dodajesz przestrzeń nazw std::.

To w niczym nie przeszkadza.


Co do twojego problemu @Evelek :

Nie tworzysz żadnych obiektów. Ten kod, który wrzucił zperkowski jest w porządku, tak więc mały przykład:

Bohater b;
Potworek p;

p.atakowanie(&b);

Btw. atakowanie bez powodu jest wirtualna. 

Super, że odwołujesz mnie do kursu Pasja Informatyki. Oglądałem go już kilkanaście razy. 

Nie wiem jak ty go oglądałeś, skoro zapomniałeś o tworzeniu obiektów :D Obejrzyj jeszcze raz.

2
komentarz 26 października 2016 przez Evelek Nałogowiec (28,960 p.)

Dziękuje za wypowiedzi do tematu.

@zperkowski - słyszałem o funkcjach wirtualnych, ale jeszcze ich tak bardzo nie analizowałem. Dziękuje za przykład i wytłumaczenie. Przynajmniej pokazałeś taki przykład, gdzie uruchomiła mi się wyobraźnia i wyobraziłem sobie mniej więcej jak mogą wyglądać programy obiektowe. smiley

@Zaćwilichowski - twój komentarz również zapamiętam. smiley

@Criss - potrafię tworzyć obiekty i metody w klasach, nawet konstruktory ogarniam i destruktory. laugh Kod, który wkleiłem się przestał kompilować na etapie tworzenia metod, więc nie było potrzeby dopisywać i tworzyć obiekty. smiley

Pora się wziąć za naukę. smiley

Podobne pytania

0 głosów
1 odpowiedź 204 wizyt
pytanie zadane 13 listopada 2016 w C i C++ przez alchem Obywatel (1,210 p.)
0 głosów
2 odpowiedzi 159 wizyt
0 głosów
1 odpowiedź 868 wizyt
pytanie zadane 11 marca 2017 w HTML i CSS przez Daniel Kudyba Obywatel (1,260 p.)

92,584 zapytań

141,434 odpowiedzi

319,671 komentarzy

61,968 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...