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

problem z klasami - dynamic_cast c++

Object Storage Arubacloud
0 głosów
486 wizyt
pytanie zadane 26 kwietnia 2017 w C i C++ przez heros22pt Użytkownik (950 p.)
edycja 29 kwietnia 2017 przez heros22pt

Piszę grę arkanoid (z pomocą openGL) i mam pewien problem.. Generalnie gra prawie działa, piłka lata, odbija się, ale nie zbija klocków.. do klocków wykorzystuję klasę cKlocek, która dziedziczy po cProstokat... cProstokat ma wszystkie funkcje sciany itd., a cKlocek ma dodatkowo atrybut odporność, która powinna spadac wraz z kolejnym zetknieciem się pilki z klockiem. Niestety funkcja dynamic_cast nie rozróżnia klocka od prostokąta. Podczas debugowania przydziela zarówno pierwszemu jak i drugiemu wartość NULL...

Wstawiam część kodu, którą opisuję. Jeśli pokazać jakąś klasę piszcie, ponieważ nie jestem w stanie wsadzić całego kodu, który jest zawarty w 16 plikach. Proszę o pomoc, ponieważ siedzę nad tym debugowaniem już drugi dzień.

void cScena::odbij()
{

	for (int i = 0; i < tab.size(); i++)
	{
		for (int k = i + 1; k < tab.size(); k++)
		{	
	
			if (tab[i]->Kolizja(*tab[k]))
			{		
				cKlocek* klocek = dynamic_cast<cKlocek*>(tab[k]);
				if (klocek != NULL){
					cout << "x";
					klocek->odjacOdpornosc();				
				}
			}
		}
	}
}

 

2 odpowiedzi

0 głosów
odpowiedź 26 kwietnia 2017 przez Evelek Nałogowiec (28,960 p.)
Nie jest to raczej przyczyna problemu, ale wspomnę, iż od C++11 zamiast NULL można stosować nullptr.
komentarz 26 kwietnia 2017 przez heros22pt Użytkownik (950 p.)
także próbowałem, nadal nic.
Chodzi mi chociaż o to, by na konsoli wyświetlić "x", który napisałem w kodzie, oznaczałoby to, że klocek jest rozróżniany, dalej już sobie poradzę. Masz może jakąś sugestię co powinienem zrobić?
komentarz 26 kwietnia 2017 przez Evelek Nałogowiec (28,960 p.)

dynamic_cast tworzy wskaźnik typu klasy pochodnej ze wskaźnika typu klasy bazowej. Jeśli taka konwersja nie jest możliwa, operator zwraca wskaźnik pusty. Widocznie w Twoim przypadku tak właśnie się dzieje - zostaje zwrócony wskaźnik pusty.

Według mnie: tab[k] - powinien być obiektem klasy pochodnej, albo klasy cKlocek, aby możliwe było rzutowanie z użyciem dynamic_cast. Krótka definicja:

dynamic_cast<Type *>(obiekt)

Wyrażenie to przekształca wskaźnik obiekt na wskaźnik na typ Type, jeśli wskazywany obiekt (*obiekt) jest klasy Type lub klasy pochodnej od Type.

komentarz 26 kwietnia 2017 przez heros22pt Użytkownik (950 p.)
mam stworzone na planszy dwa obiekty klasy pochodnej "class cKlocek : public cRectangle"

po zderzeniu z nimi piłka odbija się, tak samo jak od obiektu typu cRectangle, jednakże, ta operacja nie zwraca innej wartości niż NULL, mimo, że jest kontakt z klasą pochodną
0 głosów
odpowiedź 27 kwietnia 2017 przez j23 Mędrzec (194,920 p.)

Dodaj do klasy bazowej cRectangle(?) choć jedną metodę wirtualną (np. destruktor).

 

komentarz 29 kwietnia 2017 przez heros22pt Użytkownik (950 p.)
niestety i to nie działa :/
komentarz 29 kwietnia 2017 przez j23 Mędrzec (194,920 p.)
edycja 29 kwietnia 2017 przez j23

Jeśli tab jest tablicą wskaźników cRectangle*, a cKlocek jest pochodny od cRectangle, to nie ma bata, rzutowanie dynamic_cast musi działać (o ile mamy do czynienia z klasą polimorficzną, a wskaźnik, który chcesz rzutować, jest faktycznie obiektem klasy cKlocek).

komentarz 29 kwietnia 2017 przez heros22pt Użytkownik (950 p.)
komentarz 29 kwietnia 2017 przez j23 Mędrzec (194,920 p.)

Hierarchia dziedziczenia wygląda ok, metody wirtualne są, zatem rzutowanie powinno działać. Pewny jesteś, że w trakcie rzutowania tab zawiera wskaźniki na cKlocek?

 

Inna opcja, bardzo mało prawdopodobna, jest taka, że masz wyłączone RTTI.

komentarz 29 kwietnia 2017 przez heros22pt Użytkownik (950 p.)
tak, ponieważ klocek dodany do tab jest wyświetlany na ekranie. Działa także, jeśli ręcznie ustawię jego widoczność na 0, to znika, więc ta część też jest ok. Nie działa tylko to nieszczęsne rozpoznawanie.... nie mam już na to pomysłów, od paru godzin to debuguje
komentarz 29 kwietnia 2017 przez j23 Mędrzec (194,920 p.)

A to działa:

cFigura *p1 = new cKlocek;
	
cKlocek* p2 = dynamic_cast<cKlocek*>(p1);
if(p2) 
    cout << "casting ok\n";

 

?

komentarz 29 kwietnia 2017 przez heros22pt Użytkownik (950 p.)
tak, w tym przypadku działa. Czyli co powinienem zmienić?
komentarz 29 kwietnia 2017 przez j23 Mędrzec (194,920 p.)
Porównaj adresy klocka przy tworzeniu i rzutowaniu.
komentarz 29 kwietnia 2017 przez heros22pt Użytkownik (950 p.)
masz może pomysł co może być tego przyczyną?
komentarz 29 kwietnia 2017 przez j23 Mędrzec (194,920 p.)
edycja 29 kwietnia 2017 przez j23

Sprawdzałeś, czy w trakcie wywołania cScena::odbij w tab na pewno są wskaźniki na obiekty cKlocek stworzone w cScena::rysujScene? (chodzi mi konkretnie o adresy)

 

Tak nawiasem:

//=0 oznacza ze metoda jest abstrakcyjna, czyli nie da sie jej w tej klasie zdefiniowac

Nieprawda. Metody czysto wirtualne mogą zawierać implementacje.

Podobne pytania

0 głosów
2 odpowiedzi 131 wizyt
pytanie zadane 10 listopada 2020 w C i C++ przez sebaaas Początkujący (350 p.)
+1 głos
1 odpowiedź 178 wizyt
pytanie zadane 9 czerwca 2015 w C i C++ przez Łukasz Świtaj Użytkownik (520 p.)
0 głosów
1 odpowiedź 687 wizyt
pytanie zadane 11 grudnia 2017 w C i C++ przez seba360pl Początkujący (260 p.)

92,551 zapytań

141,393 odpowiedzi

319,523 komentarzy

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

...