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

Konstruktor a klasy pochodne

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

Witam,

Mam pewien problem, mianowicie po stworzeniu konstruktora klasy Postać, przy dziedziczącej z niej klasie Lokacja występuje błąd: "error: no matching function for call to 'Postac::Postac()". Znalazłem na forum coś takiego, chyba to jest rozwiązanie problemu, ale nie wiem jak to zapisać aby działało: 

Jeśli zdefiniujesz w klasie konstruktor z argumentami, to automatycznie traci ona konstruktor domyślny - musisz go ręcznie stworzyć. Obiekt klasy pochodnej wywołuje automatycznie konstruktor domyślny klasy bazowej, ale tylko wtedy, gdy istnieje - gdy go nie ma, musisz go stworzyć lub wywołać jawnie inny konstruktor w liście inicjalizacyjnej.

Tutaj kawałki kodu:

Klasa Postać:

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

 using namespace std;


    class Postac
    {

    public:

        int zdrowie;
        int mana;
        int sila;
        int zrecznosc;
        int talent_mag;
        int akt_zdrowie;
        int akt_mana;
        int lvl;
        int exp;
        string klasa;

        Postac (int, int, int, int, int, int, int, int, int, string);

            void statystyki();
            void wybierz_klase();
    };

Konstruktor klasy Postać:

Postac::Postac(int hp, int mp, int st, int zr, int tm, int a_z, int a_m, int lv, int ex, string k)
{
    zdrowie = hp;
    mana = mp;
    sila = st;
    zrecznosc = zr;
    talent_mag = tm;
    akt_zdrowie = a_z;
    akt_mana = a_m;
    lvl = lv;
    exp = ex;
    klasa = k;
}

Klasa Lokacja: 

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

 using namespace std;


class Lokacja :public Postac
{

    public:

            void staty();

};

 

3 odpowiedzi

0 głosów
odpowiedź 29 marca 2017 przez koczurekk Gaduła (3,420 p.)

Konstruktor domyślny klasy Lokacja powinien przekazywać parametry konstruktorowi Postac.

class Lokacja : public Postac {
public:
    Lokacja()
        : Postac(/* argumenty */)
    { }
}

Btw Lokacja to nie Postac, więc masz ewidentnie złą hierarchię klas.

0 głosów
odpowiedź 29 marca 2017 przez tangarr Mędrzec (154,860 p.)

Klasa postać nie posiada konstruktora domyślnego, więc klasa lokacja nie potrafi zainicjalizować klasy bazowej.
 

class Lokacja :public Postac
{
 
    public:
            Lokacja() : Postac( argumenty_konstruktora ) {}
            void staty(); 
};

PS. Serio? Lokacja jest postacią? Nigdy nie widziałem, żeby lokacja zaczęła się poruszać i atakować gracza.
Być może Lokacja i Postać powinny bazować na innej klasie (np ObiektGry)

komentarz 29 marca 2017 przez akiihombre Początkujący (250 p.)
Tak jak napisałem niżej. W ten sposób najłatwiej było mi przekazać właściwości klasy Postać do klasy Lokacja. Jako, iż będzie to gra tekstowa, to tych właściwości używałbym bardzo, bardzo często i wydaje mi się to w jakikolwiek sposób logiczne. Pewnie maksymalnie niepoprawne, ale działa.

Tylko właśnie ten sposób prawdopodobnie prowadzi w ślepy zaułek, do przeszkody której nie przeskoczę, dlatego "to że działa" jest tylko chwilowym sukcesem.
komentarz 29 marca 2017 przez tangarr Mędrzec (154,860 p.)
Może rozwiniesz co rozumiesz przez "przekazanie właściwości". Możesz dać przykładowy kod z użyciem tego mechanizmu. Na pewno uda się coś na to poradzić.
komentarz 29 marca 2017 przez akiihombre Początkujący (250 p.)

W klasie Lokacja jest metoda, która ma wyświetlić to co niżej:

<Mag HP:100 MP:250     LVL: 1>

Te wszystkie dane takie jak HP, MP, LVL muszę pobrać z klasy postać. Powiedzmy, że ta metoda wygląda tak:

void Lokacja::staty()
        {
            SetColor(27);
            cout << "<" << klasa << " HP: "<< akt_zdrowie << " MP: " << akt_mana<< "       LVL: " << lvl << ">";
            SetColor(15);
        }

Tak więc muszę jakoś przekazać własności klasa, akt_zdrowie, akt_mana, lvl z klasy Postać do klasy Lokacja. Jak dotąd dziedziczenie załatwiało sprawę, bo metoda staty bez problemu widziała te zmienne. Zaprzyjaźnienie nie działało, ale możliwe, że robiłem coś źle.

Także muszę znaleźć metodę na przekazanie tych zmiennych. 

komentarz 29 marca 2017 przez tangarr Mędrzec (154,860 p.)

Twoja postać i lokacja są przechowywane w jakimś obiekcie nadrzędnym (lub są zmiennymi globalnymi). Powinieneś napisać funkcję wyświetlającą najpierw opis lokacji (używając obiektu klasy Lokacja) a następnie wyświetlającą statystyki gracza (używając obiektu klasy Postac).

class Lokacja {
public:
    void opisLokacji();
};

class Postac {
public:
    void staty();
}

class Gra {
public:
    void wyswietlLokacje() {
        lokacja->opisLokacji();
        postac->staty();
    }
private:
    Postac *gracz;
    Lokacja * lokacja;
}

 

0 głosów
odpowiedź 29 marca 2017 przez mokrowski Mędrzec (155,460 p.)
Dostałeś dobrą hierarchię klas w wątku: https://forum.pasja-informatyki.pl/239410/polimorfizm-zmienne-jednej-klasy-w-drugiej Brniesz w ślepą uliczkę z tym pokrewieństwem Postać<->Lokacja.
komentarz 29 marca 2017 przez akiihombre Początkujący (250 p.)

Jeśli mam być szczery to tego kodu mało co rozumiem. Głównie ze względu na zupełne nieobycie się z kodem bez namespace std

Pokrewieństwo wzięło się stąd, że tak potrafiłem przekazać właściwości z klasy Postać do klasy Lokacja. Pewnie istnieje lepszy, bardziej logiczny i właściwy sposób, którego nie znam. 

komentarz 29 marca 2017 przez mokrowski Mędrzec (155,460 p.)

No to dopisz using namespace std;  na początku i usuń każde wystąpienie std:: :-)  Będziesz miał kod do którego jesteś przyzwyczajony.

Właściwości przekażesz jak to pokazałem w konstruktorze. Popatrz że przekazuję Postać do Lokacji poprzez metody dodajPostac(... ) i usuwam w usunPostać(...). Przecież Twój Mag, wchodzi do lokacji a później z niej wychodzi. Tak się także składa że w lokacji może być kilka postaci. Raczej nie dzieje się tak że tworzenie lokacji dodaje także postać. Lokacja może być przecież pusta. Tak więc przekazywanie postaci w konstruktorze lokacji jest nielogiczne.

komentarz 29 marca 2017 przez akiihombre Początkujący (250 p.)

Tylko myślę, że wychodzenie z lokacji nie będzie potrzebne.

Myślę, że kwestię lokacji załatwię tak, że wpisując np. karczma będąc w odpowiednim miejscu odpali się zdefiniowana wcześniej procedura karczmy. Tak samo w przechodzeniem do następnej lokacji. Coś w stylu sieci połączonych metod. Dlatego jedyne co potrzebuję to przekazanie właściwości z klasy np. Maga do klasy Lokacja. Będzie to wyglądać mniej więcej tak:

(WZÓR PODSTAWOWEJ LOKACJI W GRZE)

 

<Mag HP:100 MP:250     LVL: 1>       // TO POTRZEBUJĘ POBRAĆ Z KLASY POSTACI

Lorem ipsum dolor sit amet, consectetur adipiscing elit. In at tincidunt libero. Sed dui neque, placerat a nulla lacinia, molestie porttitor diam.

    Strażnik1
    Strażnik2
    Żebrak
    Mieszkaniec

karczma, north, south, east, west


 Tylko kolejnym problemem jest przyszłe dodanie innych klas postaci. Dlatego muszę zrobić to w taki sposób, że w zależności od ustawionego na odpowiedni obiekt klasy np. Mag, Wojownik pobrane zostaną odpowiadające im właściwości. Nie da się tego rozwiązać np wysyłając właśnie ten wskaźnik do metody? Takie coś wydaje się jak najbardziej logiczne, bo w końcu wywołuje metody tych klas poprzez kto -> statystyki();. 

1
komentarz 29 marca 2017 przez mokrowski Mędrzec (155,460 p.)

Myślę że odzwierciedlając rzeczywistość, będziesz miał łatwiejszą do opanowania aplikację. Jeśli zdefiniujesz Lokację która posiada atrybuty: north, south, east, west (a może nawet up, down), w sposób naturalny zbudujesz mapę świata. Łącz nie metodami a odniesieniami do innych lokacji. 

Jeśli Lokacja będzie trzymała odniesienia do postaci w niej umieszczonych to łatwo wyświetli informację kto w niej przebywa. Jeśli także utrzymasz sugestię by zachować proponowane dodajPostac(...) i usunPostac(...), to postać "przejdzie łatwo" do następnej lokacji.

Myślę że także to Postać powinna być nośnikiem własnych właściwości. Jeśli dodasz w niej metodę getZdolnosci() (lub inną z nazwą pokazującą intencje) na Postaci, to powinna ona zwrócić Zdolności do Lokacji która je wyświetli :-) Nie rób tego na wskaźnikach do metody bo to nie jest mechanizm przewidziany do takich celów (co najważniejsze), a po drugie wskaźniki do metody w klasie to "mały koszmarek składniowy" nie na Twoim poziomie zaawansowania (zapytaj kogo chcesz....). 

Podobne pytania

0 głosów
1 odpowiedź 642 wizyt
pytanie zadane 20 lutego 2016 w C i C++ przez Turqus Obywatel (1,420 p.)
0 głosów
1 odpowiedź 192 wizyt
pytanie zadane 22 maja 2017 w C i C++ przez Sensej Użytkownik (540 p.)
0 głosów
1 odpowiedź 904 wizyt
pytanie zadane 17 lutego 2017 w C i C++ przez Miszo Bywalec (2,100 p.)

92,576 zapytań

141,426 odpowiedzi

319,651 komentarzy

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

...