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

question-closed Błędy przy wskaźnikach?

0 głosów
424 wizyt
pytanie zadane 12 lipca 2015 w C i C++ przez criss Mędrzec (172,570 p.)
zamknięte 17 listopada 2016 przez criss

Powoli pisze sobie gierke w konsoli. Mam problem przy nakładaniu przedmiotów (na postać). Przedmioty są podzielone na kilka klas typu zbroja, helm itd. Wszystkie dziedziczą z jednej klasy wirtualnej, zalozmy Cloth.
Ekwipunek jest wektorem wskaźników Cloth. Poniżej funkcje klasy postaci odpowiedzialne za nakładanie/zdejmowanie przedmiotów (dla broni funkcja jest przeciążona z widocznych powodów) :

template <class T>
void cloth_on(T* w)
{
   if(this->hlvl>=w->lvl){
     this->def+=w->def;
     if(w->bid!=0){
                     if(w->bid==1) this->maxhp+= w->b_pow;
                     else if(w->bid==2) this->def+= w->b_pow;
                     else if(w->bid==3) this->rzuty+= w->b_pow;
                     else if(w->bid==4) this->dmg+= w->b_pow;
                     else if(w->bid==5) this->crt+= w->b_pow;
                  }
     w->on=true;
   }
}

void cloth_on(Miecz* w)
{
     if(this->hlvl>=w->lvl)
     {
               w->on=true;
               rzuty+=w->rzuty;
               dmg+=w->dmg;
               crt+=w->crt;
        if(w->bid!=0){
                     if(w->bid==1) this->maxhp+= w->b_pow;
                     else if(w->bid==2) this->def+= w->b_pow;
                     else if(w->bid==3) this->rzuty+= w->b_pow;
                     else if(w->bid==4) this->dmg+= w->b_pow;
                     else if(w->bid==5) this->crt+= w->b_pow;
                  }
              }
}

template <class U>
void cloth_off(U* w)
{
     this->def-=w->def;
     if(w->bid!=0){
                     if(w->bid==1) this->maxhp-= w->b_pow;
                     else if(w->bid==2) this->def-= w->b_pow;
                     else if(w->bid==3) this->rzuty-= w->b_pow;
                     else if(w->bid==4) this->dmg-= w->b_pow;
                     else if(w->bid==5) this->crt-= w->b_pow;
                  }
     w->on=false;
}
void cloth_off(Miecz* w)
{
              w->on=false;
              rzuty-=w->rzuty;
              dmg-=w->dmg;
              crt-=w->crt;
        if(w->bid!=0){
                     if(w->bid==1) this->maxhp-= w->b_pow;
                     else if(w->bid==2) this->def-= w->b_pow;
                     else if(w->bid==3) this->rzuty-= w->b_pow;
                     else if(w->bid==4) this->dmg-= w->b_pow;
                     else if(w->bid==5) this->crt-= w->b_pow;
                  }
}

Konkretnie chodzi o to, że postać dostaje kompletnie randomowe wartości obrony, dmg itd. W przypadku obrony są to czesto liczby olbrzymie, ale czasami też zero. Wspominam o tym, bo w przypadku innych statystyk są to liczby znacznie bliżej tej właściwej. Dmg i rzuty są czasami nawet dodawane poprawnie :D . Przy zdejmowaniu jest odejmowana ta sama wartość która została dodana przy założeniu.
Wywołania wyglądają tak:

h.cloth_off(v[choice]);

h.cloth_on(v[choice]);

hero - obiekt klasy postaci, v- wektor ekwipunku

komentarz zamknięcia: .

2 odpowiedzi

0 głosów
odpowiedź 12 lipca 2015 przez Buby Pasjonat (19,590 p.)
wybrane 12 lipca 2015 przez criss
 
Najlepsza

Kolego, a mam takie jedno pytanie - czy konstruktor domyślny postaci zeruje startowo te wartości, bądź inicjalizuje jakąś wartością? Bo jeśli nie, to wartości, które dodaje funkcja są sumowane ze śmieciami, które znajdowały się w pamięci poprzednio. Mógłbyś pokazać jeszcze kod konstruktora klasy postaci oraz listę jej składowych?

 

@Edit:

Poza tym, ja w pierwszej kolejności przetestowałbym jakie wartości zawiera twoja składowa b_pow.

Możesz np. zmodyfikować kod w ten sposób i stwierdzić, czy wartości które przechowuje są poprawne dodając np. operację wyjścia w którymś z if'ów. :)

komentarz 12 lipca 2015 przez criss Mędrzec (172,570 p.)
Tak, na początku wszystkie jest równe 0. Z resztą zauważyłbym, bo wartości widze zawsze w aktualnym stanie. W konstruktorze jest tylko nadawanie wartości atrybutom i nic więcej.
komentarz 12 lipca 2015 przez criss Mędrzec (172,570 p.)
Upewniłem się, że b_pow zawsze przechowuje to, co chce (ew. 0).
To na pewno nie jest nic w konstruktorze - same przedmioty mają poprawne wartości. Coś się dzieje nietak przy ich odczycie.
komentarz 12 lipca 2015 przez Buby Pasjonat (19,590 p.)

Hmm...A jak wygląda przykładowa funkcja na podstawie której wnioskujesz wartość zmiennych? Być może tam coś jest nie tak.

A wynik takiego kodu daje poprawne wartości wewnątrz funkcji?

template <class T>
void cloth_on(T* w)
{
   if(this->hlvl >= w->lvl){
	 std::cout << "Obrona postaci: " << this->def << std::endl;
	 std::cout << "Zwiększam o: " << w->def << std::endl;
	 this->def+=w->def;
	 std::cout << "Teraz obrona: " << this->def << std::endl;
     if(w->bid != 0){
                     if(w->bid==1) this->maxhp+= w->b_pow;
                     else if(w->bid==2) this->def+= w->b_pow;
                     else if(w->bid==3) this->rzuty+= w->b_pow;
                     else if(w->bid==4) this->dmg+= w->b_pow;
                     else if(w->bid==5) this->crt+= w->b_pow;
                  }
     w->on=true;
   }
}

 

komentarz 12 lipca 2015 przez criss Mędrzec (172,570 p.)

Nie, to samo. 
Przy okazji: zauważyłem, że wartości nadawane w ifie if(w->bid != 0) są zasze poprawne. Sprawdzałem też czy przypadkiem program nie myli funkcji których ma użyć (tzn. wersji dla Miecz używa dla innych przedmiotów lub odwrotnie), ale nie - ciągle to samo.

komentarz 12 lipca 2015 przez Buby Pasjonat (19,590 p.)
A pokaż pełne deklaracje klas, oczywiście jeśli możesz. Może rzuci mi się coś w oczy, bo powoli kończą mi się pomysły. :/
komentarz 12 lipca 2015 przez criss Mędrzec (172,570 p.)

*.h: http://pastebin.com/9cenEyvq
*.cpp: http://pastebin.com/zmUUPtqx

cloth_on i off dla miecza są zakomentowane, bo zmieniłem na uniwersalne i nie są potrzebne. Potzrebne mi to było do sprawdzenia czy na pewno nie chodzi o wykorzystywanie nie tej funkcji co trzeba.

komentarz 12 lipca 2015 przez Buby Pasjonat (19,590 p.)
Mam pytanie - po co redefiniujesz składowe w klasach pochodnych - klasy które dziedziczą publicznie po Cloth, posiadają publiczne składowe tejże klasy - a ty w klasie pochodnej miecz tworzysz jeszcze jedną składową o tej nazwie np. dmg - nie mam pojęcia, czy ona czasem nie przykrywa odziedziczonej składowej i czy to ma jakiś wpływ, ponieważ takiej wersji kodu nie testowałem, ale wg mnie ten dodatkowy zapis jest zbędny, bo przecież klasa posiada już taką składową. Spróbuj pousuwać zbędne definicje zmiennych, lub je zakomentarzuj.
komentarz 12 lipca 2015 przez criss Mędrzec (172,570 p.)
Dodawałem je na szybko przed chwilą :P za chwile zobacze.
komentarz 12 lipca 2015 przez Buby Pasjonat (19,590 p.)
Na 90% to jest problemem - używasz wskaźnika do klasy cloth, więc posługując się wskaźnikiem this używasz wartości składowej z tej klasy, ponieważ przechowujesz adres obiektu w wskaźniku polimorficznym.

A tworząc klasę inicjalizujesz składową klasy pochodnej, a nie bazowej. Proszę, powiedz, że teraz działa, bo to jest pomysł ostateczny i logicznie wyjaśnia dlaczego tak się dzieje.
komentarz 12 lipca 2015 przez criss Mędrzec (172,570 p.)

Cóż, wzystkie przedmioty poza klasą Miecz są zakładane i zdejmowane poprawnie. Ale w Mieczu atrybuty zawsze są odejmowane o_O pole on zmienia sie poprawnie, ale reszta jest odejmowana niezależnie od użytej funkcji.

update: jeszcze pokombinuje, ale wieczorem, narazie musze lecieć.

komentarz 12 lipca 2015 przez Buby Pasjonat (19,590 p.)

Okej, daj znać, czy się udało.

A tutaj przykład czego NIE robić i dlaczego.

#include <iostream>

class A
{
    public:
        int x;
        A(){}
};

class B: public A
{
    public:
        int x;
        B(int n): x(n){}
};

int main( void )
{
    B Obiekt(10);
    A* Wskaznik = &Obiekt;

    std::cout << "Kiedy odczytuje z obiektu pochodnego: " << Obiekt.x << std::endl;
    std::cout << "Kiedy odczytuje z wskaznika polimorficznego na klase bazowa: " << Wskaznik->x << std::endl;

    return 0;
}

Output:

Kiedy odczytuje z obiektu pochodnego: 10
Kiedy odczytuje z wskaznika polimorficznego na klase bazowa: 4272976

 

komentarz 12 lipca 2015 przez criss Mędrzec (172,570 p.)
Ok, już wszystko ładnie działa :D Kopiowałem część kodu i zapomniałem zamienić - na +. Dzięki za pomoc :)
0 głosów
odpowiedź 12 lipca 2015 przez Dorion300 Szeryf (90,250 p.)
Mógłbyś podać kod "h.cloth_on"?

Jak i prostą definicję klasy tego clouthu. (przedmiotu)

Podejrzewam że błąd jest w cloth_on gdyż zły adres pobiera.

Albo w obiekcie przedmiotu gdyż dziwną wartośc posiada.

 
Zrób test -- stwórz przedmiot a następnie sprawdz statystyki czy wszystko ok.

Jeśli tak to problem leży w metodzie.
komentarz 12 lipca 2015 przez criss Mędrzec (172,570 p.)

Zrób test -- stwórz przedmiot a następnie sprawdz statystyki czy wszystko ok.

W obiekcie przedmiotu jest wszystko ok.
Kod jest w spoilerze.
 

komentarz 12 lipca 2015 przez Dorion300 Szeryf (90,250 p.)

Nie żebym wnikał ale nie powinno być?:

h.cloth_on<Tutaj_wpisz_tyb_zmiennej>(v[choice]);

 

 

komentarz 12 lipca 2015 przez criss Mędrzec (172,570 p.)
Przy wywołaniu na pewno nie. Przy definicji/deklaracji tak, ale w specjalizacjach szablonów bodajze, tutaj mam zwykłe przeciążenie.
komentarz 12 lipca 2015 przez Buby Pasjonat (19,590 p.)
Nie, ponieważ to jest funkcja szablonowa, a nie cała klasa.
komentarz 12 lipca 2015 przez Dorion300 Szeryf (90,250 p.)
Wiem że to jest funkcyjna.

Ale co ma Miecz do ubrania? (np. zakładasz pierścień za pomocą w której zakładasz miecz)

no chyba że ekwipujesz broń to zwracam honor.

Podobne pytania

0 głosów
1 odpowiedź 953 wizyt
0 głosów
1 odpowiedź 215 wizyt
pytanie zadane 14 listopada 2015 w C i C++ przez Kloda Użytkownik (760 p.)
0 głosów
1 odpowiedź 627 wizyt

93,424 zapytań

142,421 odpowiedzi

322,643 komentarzy

62,782 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

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
...