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

Polimorfizm - zmienne jednej klasy w drugiej

Object Storage Arubacloud
0 głosów
288 wizyt
pytanie zadane 28 marca 2017 w C i C++ przez akiihombre Początkujący (250 p.)
edycja 28 marca 2017 przez akiihombre

Witam.

Mam pewien problem związany z klasami w C++. Mam klasę Mag utworzoną z abstrakcyjnej klasy Postać i chcę użyć jej zmiennych w odrębnej klasie Lokacja. Tylko nie wiem w jaki sposób je przekazać. 

Na razie istnieje tylko jedna klasa utworzona polimorficznie. Na razie chcę dopracować wszystko na jednej klasie, dodając później tylko kolejne mając już podstawę. 

KLASA ABSTRAKCYJNA I KLASA POSTAC

#include <iostream>
#include <windows.h>
#include <cstdlib>

 using namespace std;



    class Postac
    {
        friend class Lokacja;

    public:

        virtual void statystyki() = 0;
    };




    class Mag :public Postac
    {
            friend class Lokacja;

        int zdrowie = 75;
        int mana = 125;
        int sila = 10;
        int zrecznosc = 12;
        int talent_mag = 2;
        int akt_zdrowie = 75;
        int akt_mana = 125;
        int lvl = 1;
        int exp = 1;

    public:

            void statystyki();
    };

KLASA LOKACJA

#include <iostream>
#include <windows.h>
#include <cstdlib>

 using namespace std;

class Lokacja
{
    void staty();     // W tej metodzie chce uzyc zmiennych z klasy Postac,
};                    // powiedzmy, że zmiennej lvl

A w ten sposób rozwiązałem ustawianie wskaźnika:

    Mag mg;

    Postac *kto;
    kto = &mg;

 

Nie wiem po prostu jak wykorzystać np. zmienną lvl w klasie Lokacja. Wysłać tam wkaźnik jako argument? Bo stricte obiektu nie mogę wysłać, ze względu na to, że w przyszłości dodam kilka innych klas wybieranych poprzez switcha, a to będzie wymagało powielenia kodu dla każdej z klas. Myślę, że da się to rozwiązać unikając niepotrzebnej redundancji.

komentarz 29 marca 2017 przez akiihombre Początkujący (250 p.)
Nie da się wysłać wskaźnika ustawionego na dany obiekt i wtedy pobrać wartości zmiennych?

Tylko coś takiego mi dotąd przyszło do głowy, ale nie wiem jak to zapisać (o ile to możliwe).

2 odpowiedzi

0 głosów
odpowiedź 28 marca 2017 przez Kasztan Dyskutant (8,080 p.)
A klasa lokacja nie moze dziedziczyc po klasie Mag ?

I wtedy jakąś metodę w klasie Lokacja, która użyje zmiennej lvl ? np ją wyświetli lub zinkrementuje
komentarz 28 marca 2017 przez akiihombre Początkujący (250 p.)
Właśnie problem polega na tym, że gdy w przyszłości będą powiedzmy 4 klasy, to każda z nich będzie miała inne statystyki startowe (takie jak np. siła, zręczność), a przy tej metodzie musiałbym w sumie kopiować cztery razy to samo. Szukam po prostu sposobu (jeśli taki w ogóle jest, ale raczej tak), aby zapisać to raz, od razu dla każdej innej klasy.
komentarz 28 marca 2017 przez Kasztan Dyskutant (8,080 p.)
takie atrybuty jak lvl, zdrowie, mana itp będzie miała każda postać więc myślę, że źle przypisałes propertisy :) powinny one być w klasie postać

W sensie że od klasy postać utworzy np mag, wojownik i dla nich będą inne wartości składowych czy tam inne metody :) rozumiesz ? o co mi chodzi ?
komentarz 28 marca 2017 przez akiihombre Początkujący (250 p.)
Faktycznie, te propertisy dla każdej klasy będą takie same. Każda będzie miała zdrowie, manę, etc. tylko różnić się będą one liczbami. I właśnie te liczby muszę pobrać.

Np. gracz wybiera klasę Mag. Na ekranie pojawiają się za każdym razem statystyki. W tym przypadku będzie to <Mag HP:75 MP:125    LVL:1> lub coś w tym stylu.

Jednak gdy gracz wybierze klasę wojownika (którą dodam w przyszłości) to na ekranie ma pojawić się to samo, tylko z innymi liczbami. np. <Wojownik HP:125 MP:75    LVL:1>.

Gdybym działał tylko na propertisach z klasy Postać to za każdym razem były by one takie same. Właśnie w tym jest problem - jak to zapisać, żeby zależnie od wyboru pobierane były dane właściwości z danej klasy.
0 głosów
odpowiedź 29 marca 2017 przez mokrowski Mędrzec (155,460 p.)

Tu masz szkic:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdlib>

struct PostacZdolnosci {
    int zdrowie;
    int mana;
    int sila;
    int zrecznosc;
    int talent_mag;
    int akt_zdrowie;
    int akt_mana;
    int lvl;
    int exp;
};

class Postac {
    PostacZdolnosci zdolnosci;
    std::string nazwa; // lub inne jeszcze wspólne atrybuty..
public:
    Postac(const std::string& nazwa): zdolnosci{}, nazwa{nazwa} {}
    void wczytajZdolnosci(const PostacZdolnosci& zdolnosci_) {
        zdolnosci = zdolnosci_;
    }
    virtual void statystyki() const {
        // Tu sobie wyświetlisz statystyki ze zdolności
        // a dzięki virtual (jeśli to będzie konieczne), 
        // przeciążysz wyświetlanie dla np. potworów.
        std::clog << "Wyświetlenie statystyk postaci " << nazwa << '\n';
        std::clog << "Zdrowie: " << zdolnosci.zdrowie
            << "\nMana: " << zdolnosci.mana << "... itd\n";
    }
    virtual ~Postac() { }
};

class Mag : public Postac {
public:
    Mag(const std::string& nazwa = "Mag"): Postac(nazwa) {}
    // Jakieś metody dla Maga
};

class Lokacja {
    std::string nazwa;
    // Tu powinien być w kontenerze unique_ptr<Postac> 
    // lub shared_ptr<Postac>
    // ale nie wiem czy znasz... 
    std::vector<const Postac *> postacie;
public:
    Lokacja(const std::string& nazwa): nazwa{nazwa} {}
    void dodajPostac(const Postac* postac) {
        // dodawanie postaci do kontenera.. 
        // tu do testów.
        postacie.push_back(postac);
    }
    void usunPostac(const Postac* postac) {
        // usuwanie postaci z kontenera..
        postacie.erase(std::remove(postacie.begin(),
                    postacie.end(), postac), postacie.end());
    }
    void statystyki() const {
        std::clog << "======================================\n";
        std::clog << "W lokacji " << nazwa << " jest obecny:\n";
        for(const auto& postac: postacie) {
            postac->statystyki();
        }
        std::clog << "======================================\n";
    }
    ~Lokacja() {
        // Ze unique/shared było by łatwiej.. 
        for(auto& postac: postacie) {
            delete postac;
        }
    }
};

int main() {
    auto m1 = Mag("Rysiek");
    m1.wczytajZdolnosci({75, 125, 10, 12, 2, 75, 125, 1, 1});
    auto l1 = Lokacja("Pizzeria");
    l1.dodajPostac(&m1);
    l1.statystyki();
    l1.usunPostac(&m1);
    l1.statystyki();
}

 

komentarz 29 marca 2017 przez Kasztan Dyskutant (8,080 p.)
Da się to zrobić bez tych bibliotek, twój problem rozwiązują konstruktory : P.

Stwórz klase postać dodaj tam metody, które cię interesują, następnie klasy postaci też jakieś unikatowe metody i konstruktorami wszystko utworzysz :)
komentarz 29 marca 2017 przez mokrowski Mędrzec (155,460 p.)
Jakich bibliotek? Przecież to szkic i to stworzony po to by pokazać ideę :-) Kolega pytał o relacje pomiędzy Lokacja/Propertis'ami/Postacią. Podstawową niezręczność jaką miał to friend który łamie reguły hermetyzacji i problem z inicjalizacją Propertisów (w szkicu PostacZdolnosci). Resztę sobie dopisze..
komentarz 29 marca 2017 przez Kasztan Dyskutant (8,080 p.)
Bez tych bibliotek

#include <string>

#include <vector>

#include <algorithm>

#include <cstdlib>

 też da się zrobić szkic, on przez te metody, iteratory przestał czytać twój kod po paru linijkach :)
komentarz 29 marca 2017 przez mokrowski Mędrzec (155,460 p.)

Jasne.. dzięki za uwagi merytoryczne :-)

Podobne pytania

0 głosów
0 odpowiedzi 107 wizyt
+1 głos
1 odpowiedź 286 wizyt
pytanie zadane 3 lutego 2016 w C i C++ przez Ziuziek Mądrala (5,140 p.)
0 głosów
0 odpowiedzi 236 wizyt
pytanie zadane 13 sierpnia 2020 w C i C++ przez lujasjeden Użytkownik (860 p.)

92,572 zapytań

141,423 odpowiedzi

319,645 komentarzy

61,959 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!

...