• 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++

VPS Starter Arubacloud
0 głosów
458 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 123 wizyt
pytanie zadane 10 listopada 2020 w C i C++ przez sebaaas Początkujący (350 p.)
+1 głos
1 odpowiedź 175 wizyt
pytanie zadane 9 czerwca 2015 w C i C++ przez Łukasz Świtaj Użytkownik (520 p.)
0 głosów
1 odpowiedź 683 wizyt
pytanie zadane 11 grudnia 2017 w C i C++ przez seba360pl Początkujący (260 p.)

92,454 zapytań

141,262 odpowiedzi

319,089 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...