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

C++ wektor zawierający obiekty dziedziczonych klas

Object Storage Arubacloud
0 głosów
1,349 wizyt
pytanie zadane 10 maja 2017 w C i C++ przez Kodeman Gaduła (4,480 p.)
Witam, chciałem stworzyć system ekwipunku do gry. Stworzyłem klasę Item i dziedziczy z niej np. Sword. Żeby móc dokonywać obliczeń itp. chciałem, by wszystkie obiekty potomków znajdowały się w jednym wektorze.

http://wklej.org/id/3109942/

Mój problem polega na tym, że wszystkie zmienne klasy Sword są ucinane, przez co każdy obiekt dodany do wektora staje się obiektem klasy Item. Próbowałem używać wskaźników jak widać, włącznie z inteligentnymi wskaźnikami, lecz efekt jest zawsze taki sam. Szukając w internecie doszedłem do wniosku, że innym powyższy kod działa. Co robię niewłaściwie i czy to w ogóle jest dobry sposób na system ekwipunku dla gry? Z góry dziękuję.

1 odpowiedź

+2 głosów
odpowiedź 10 maja 2017 przez j23 Mędrzec (194,920 p.)
wybrane 12 maja 2017 przez Kodeman
 
Najlepsza

(...) że innym powyższy kod działa.

Jakim cudem? To może zadziałać tylko tak:

class Item
{
public:
    int a;
   virtual ~Item() {} // <-- klasa powinna być polimorficzna
};

...

Sword *ptr = dynamic_cast<Sword*>(wektor[0]);
if(ptr != nullptr) cout << ptr->b;

 

1
komentarz 10 maja 2017 przez Knayder Nałogowiec (37,640 p.)

Klasa Item może mieć funkcję wirtualną use.
Potem wystarczy każdy item w wektorze iterować i wywoływać tą właśnie metodę.
Jeżeli zrobisz klasę sword dziedziczącą po Item i zdefiniujesz tą funkcją w klasie sword, to właśnie ona zostanie wywołana.
Ew. możesz użyć funkcji dynamic_cast

komentarz 11 maja 2017 przez Kodeman Gaduła (4,480 p.)
Nie bardzo rozumiem, czy pozwoli mi to posiadać obiekty o różnych wielkościach w wektorze? Szukam sposobu jak zrobić bardzo popularny w większości gier system ekwipunku, więc nie może być to trudne. Jednak faktycznie, posiadanie obiektów o różnej ilości zmiennych nasporzyłoby trudności. Zgubiłem się i nie wiem jak do tego podejść z powrotem. Dynamic_cast jest wyjściem, ale chyba nie "właściwym". Jeśli ktoś mógłby mi dostarczyć wskazówki, żebym wiedział za co się zabrać, to byłbym wdzięczny. System ekwipunku o którym mówię, to ten jak np. w minecrafcie. Zależnie jakiego jest typu obiekt, to mogę go włożyć na specjalny slot itp. Jak to się robi optymalnie?
1
komentarz 11 maja 2017 przez Knayder Nałogowiec (37,640 p.)

Napisałem ci już wcześniej (To miał być normalna odpowiedź do posta, a wyszło jako odpowiedź do innej odpowiedzi.

Masz klasę Item.
W tej klasie masz metodę wirtualną. virtual void use();

Następnie robisz klasę dziedziczącą np. class Sword : public Item;
Dodajesz w niej tą właśnie metodę wirtualną use() i definiujesz jej działanie,

Teraz wystarczy zrobić wektor "Ekwipunek" i wywoływać tą metodę dla każdego elementu.

class Item{
    virtual void use() {}
}

class Sword : public Item{
   virtual void use() override {
      //Co ma się dziać po użyciu
   }
}

int main(){
   std::vector<Item*> eq;
   eq.push_back(new Sword);
   ...
   ...
   eq[0].use();
   ...
   ...
   for(Item *item : eq)
      delete item;
}

Oczywiście klasę możesz odświeżyć o inne metody, np. update() (Wywoływana co każdą klatkę)

komentarz 11 maja 2017 przez Kodeman Gaduła (4,480 p.)
Na początku nie rozumiałem, ale sprawdziłem i faktycznie działa. http://wklej.org/id/3110764/

Wrzucam na wszelki wypadek, żeby upewnić się, że dobrze zrozumiałem(może komuś jeszcze pomoże) Dziękuję bardzo za pomoc :)
1
komentarz 11 maja 2017 przez mokrowski Mędrzec (155,460 p.)
#include <iostream>
#include <vector>
#include <memory>

using namespace std;

class Item {
  public:
    virtual void use() = 0;
    virtual ~Item();
  protected:
    int weight;
};

Item::~Item() {}

class Sword : public Item {
  public:
    Sword(int weight_, int min_damage_, int max_damage_)
        : min_damage{min_damage_}, max_damage{max_damage_} {
        this->weight = weight_;
    }
    void use() override;
    virtual ~Sword();
  private:
    int min_damage, max_damage;
};

void Sword::use() {
    std::cout << weight << std::endl;
    std::cout << min_damage << std::endl;
    std::cout << max_damage << std::endl;
    std::cout << "\n";
}

Sword::~Sword() {}

class Armor : public Item {
  public:
    Armor(int weight_, int armor_)
        : armor{armor_} {
        this->weight = weight_;
    }
    void use() override;
    virtual ~Armor();
  private:
    int armor;
};

void Armor::use() {
    std::cout << weight << "\n";
    std::cout << armor << "\n\n";
}

Armor::~Armor() {}

int main() {
    std::vector<std::unique_ptr<Item>> inventory;
    inventory.push_back(std::make_unique<Sword>(1, 2, 3));
    inventory.push_back(std::make_unique<Armor>(1, 29));
    inventory[0]->use();
    inventory[1]->use();
}

 

komentarz 12 maja 2017 przez Kodeman Gaduła (4,480 p.)
Dziękuję bardzo :)

Podobne pytania

0 głosów
1 odpowiedź 1,782 wizyt
pytanie zadane 20 kwietnia 2020 w C i C++ przez niezalogowany
0 głosów
2 odpowiedzi 498 wizyt
0 głosów
1 odpowiedź 613 wizyt

92,551 zapytań

141,399 odpowiedzi

319,531 komentarzy

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

...