webForumDet fria alternativet

ABS & Funktioner

15 svar · 408 visningar · startad av Alpha II

Alpha IIMedlem sedan maj 20002 993 inlägg
#1

Jag frågade omd etta förut men fick inget bra svar då, så jag ställer om frågan och hoppas någon kan svara denna gång. :)

Jag har klassen CObject som är en abstrakt basklass. CSpaceship och CAsteroid ärver av CObject.

De helt virituella funktionerna Update och Draw och några variabler är det enda som finns i CObject.

I CSpaceShip finns några fler funktioner som inte finns i CObject.

Nu har jag en funktion som jag kallar Collision som tar två CObjects som argument.

Den funktionen vill jag kunda använda med olika kombinationer av CSpaceShip och CAsteroid. Tex Collision(spaceship[10], asteroid[5]) ..... Collision(spaceship[10],spaceship[1])

Problemet är att när jag använder en funktion i någon av klasserna kraschar programmet. Har ingen aning varför. Jag är ganska ny i C++ och har fortfarande lite problem med klasser och pekare. Kan det vara att jag skapar objekten fel? Så är definerar jag asteroiderna och rymdskeppena. Rätt?

CObject * players = new CSpaceShip[MAX_PLAYERS];
CObject * asteroids = new CAsteroid[MAX_ASTEROIDS];

PeWMedlem sedan juni 200010 432 inlägg
#2

Så är definerar jag asteroiderna och rymdskeppena. Rätt?

Ja, men hur ser basklassen ut? Deklarerar du den pure virtual eller bara med virtual? F.ö kan det vara god ide att debugköra programmet med väl valda breakpoints för att se vart det ballar ur..

aasahMedlem sedan mars 20034 471 inlägg
#3

Hur ser Collision's definition ut? Tar den någon superklass eller har du flera överlagrade funktioner Collision (vilka tar olika typer som argument)?

Alpha IIMedlem sedan maj 20002 993 inlägg
#4

PeW->

class CObject
{
public:
	float	x;
	float	y;
	float	radie;
	float	angle;

	CObject() {}
	virtual void	Draw()=0;
	virtual void	Update()=0;
	virtual 	~CObject() {}
};

aasah-> superclass? Den tar två CObject som argument.
Collision() om det skulle vara intressant.

bool Collision(CObject * obj1, CObject * obj2)
{
	float deltaXSqr = pow(obj1->x - obj2->x, 2);
	float deltaYSqr = pow(obj1->y - obj2->y, 2);
	float sumRadii	= pow(obj1->radie + obj2->radie, 2);

	if(deltaXSqr+deltaYSqr < sumRadii)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}
Alpha IIMedlem sedan maj 20002 993 inlägg
#5

Förstpr inte....

Märkte en konstig sak. Att anropa Draw och update från ett CSpaceSHip object går utmärkt, likaså från asteroids[0]. Men om jag testar att skriva

asteroids[5].Draw();

så kraschar programmet. MAX_ASTEROIDS är satt till 20... konstigt..

aasahMedlem sedan mars 20034 471 inlägg
#6

Re: ABS & Funktioner

Alpha II skrev:

...Jag har klassen CObject som är en abstrakt basklass. CSpaceship och CAsteroid ärver av CObject.

De helt virituella funktionerna Update och Draw och några variabler är det enda som finns i CObject.

I CSpaceShip finns några fler funktioner som inte finns i CObject.

Nu har jag en funktion som jag kallar Collision som tar två CObjects som argument.

Den funktionen vill jag kunda använda med olika kombinationer av CSpaceShip och CAsteroid. Tex Collision(spaceship[10], asteroid[5]) ..... Collision(spaceship[10],spaceship[1])

Problemet är att när jag använder en funktion i någon av klasserna kraschar programmet. Har ingen aning varför. Jag är ganska ny i C++ och har fortfarande lite problem med klasser och pekare. Kan det vara att jag skapar objekten fel? Så är definerar jag asteroiderna och rymdskeppena. Rätt?

CObject * players = new CSpaceShip[MAX_PLAYERS];
CObject * asteroids = new CAsteroid[MAX_ASTEROIDS];

För det första tycker jag att din deklaration ser lite skum ut. Vad vill du att players ska vara?

En pekare till en Array med CSpaceShips deklareras:
CObject (* players)[] = new CSpaceShip[MAX_PLAYERS];

Om du däremot vill ha en array med (pekare till CSpaceShips):
CObject * players[] = new CSpaceShip[MAX_PLAYERS];

Det är möjligt att det går att skriva som du har gjort, men jag är tveksam till vad du får i så fall?

***
Sedan om det du har funkar så har du troligen en pekare till en array. I så fall kommer players[k] att vara en pekare till det k:e CObject:et i Arrayen. För att komma åt funktionen i det objekt som pekaren pekar på, måste du skriva:

players[k]->Draw() vilket är en kortform för (*players[k]).Draw() dvs du måste först avreferera pekaren så du når objektet själv.

Dessutom räcker det inte med att du har gjort new, om du inte har stoppat in något objekt på indexplats 5 t.ex. så kommer players[5] att peka på godtycklig plats i minnet. Där kan stå precis vad som helst.

***
Slutligen: De enda funktionerna du kommer åt i såväl CSpaceShip som i CAsteroid är de som finns med i gränssnittet till CObject.

stenmarkMedlem sedan apr. 200318 inlägg
#7

jag tror...

Det ligger väldigt mycket i det som aasah sa.

Om jag har fattat ditt problem så vill du använda varianten med en array med pekare till CObject. Eftersom att Collision funktonen tar just pekare till CObject.
Så använd det alternativet när du deklarar arrayen.
CObject * players[] = new CSpaceShip[MAX_PLAYERS];

Sen vet jag inte hur dina konstruktorer mm. funkar i CSpaceShip. Men du måste ju se till att det vekligen ligger något på plats 5 i fältet om du vill använda plats 5. Annars kommer det ju naturligtvis inte funka.

Alpha IIMedlem sedan maj 20002 993 inlägg
#8

Men om MAX_PLAYERS är 8 så måste det väl finnas någonting på nummer 5?

Alpha IIMedlem sedan maj 20002 993 inlägg
#9

Om jag deklarerar player så här, hur gör jag för att använda en speciell konstruktor?

CObject * players[] = new CSpaceShip[MAX_PLAYERS];

Funkar inte:
CObject * players[] = new CSpaceShip[MAX_PLAYERS] (g_Window);
stenmarkMedlem sedan apr. 200318 inlägg
#10

Ja det finns ett objekt på plats 5, men det är inte säkert att den innehåller riktig data. Du måste ju se till att initiera tex CSpaecShip med rätt koordinater mm. Annars går det ju åt skogen när collision försöker räkan på data som är odefinerad.

aasahMedlem sedan mars 20034 471 inlägg
#11

Alpha II skrev:

Om jag deklarerar player så här, hur gör jag för att använda en speciell konstruktor?

CObject * players[] = new CSpaceShip[MAX_PLAYERS];

Funkar inte:
CObject * players[] = new CSpaceShip[MAX_PLAYERS] (g_Window);

Jag tror att det är ett missförstånd här? Om vi tar ett enkelt exempel:

Vi har en klass Rectangle som innehåller int h, b (höjd och bredd), och en konstruktor som anropas med två intar. Då definierar vi en ny Rectangle så här:

Rectangle r = new Rectangle(6, 7); // T.ex.

Nu vill vi ha en array med Rectangles (jag struntar i pekare för ögonblicket.)

Rectangle ra[] = new Rectangle[10];

Vad har du nu? Jo ra är ett lagringsutrymme för 10 st Rectangles vilka inte finns än. Det som händer när du gör new är att ett visst utrymme "registreras" som att "här ligger Rectangles och heter ra*" (lite småskumt uttryckt). Tidigare programkörningar (kan) ha lämnat data i dessa minnesceller, klart är att du inte har någon som helst aning om vad de innehåller!! (Detta innehåll brukar kallas skräp.) Riktigt otrevligt kan det bli om där ligger något vars bitmönster kan tolkas som en Rectangles bitmönster. Troligast är att du får vilket skumt fel som helst... inte nödvändigtvis vid läsningen utan några rader längre fram i koden när du försöker använda din "Rectangle". Alltså måste (BÖR!) man explicit sätta alla värden i arrayen till något, antingen lägga in alla rektanglar om man har dem redan, eller sätta alla tomma platser till null. Då kan man inte längre råka jobba vidare med något skräpvärde.

Alltså

ra[0] = r;
ra[1] = new Rectangle(2, 4);
...
ra[9] = new Rectangle(7, 89);*

Alpha IIMedlem sedan maj 20002 993 inlägg
#12

CObject * players[] = new CSpaceShip[MAX_PLAYERS];

Error: { expected

stenmarkMedlem sedan apr. 200318 inlägg
#13

Det var ett lite konstigt fel. Men om jag hade gjort det programmet så hade jag gjort saker och ting i fler steg efter som att jag tycker att det är lite lättare, är själv inte speciellt bra på pekare och dynamsikt allokerade variabler :).

//Först skapar jag ett fält med pekare till CObject.
CObject *players[ MAX_PLAYERS ];
//Sen kör jag en loop som för varje varv skapar ett nytt CSpaceShip initerar det till ett slump värde inom gränsen för spelet samt sätter en pekare på *till att peka på just det skeppet.
for( int i = 0; i < MAX_PALYERS; i++ )
players[ i ] = new CSpaceShip( rand() % MAX_PIXEL,
rand() % MAX_PIXEL );

Är inte 100% säker på att det funkar...men du kan ju testa.*

aasahMedlem sedan mars 20034 471 inlägg
#14

Alpha II skrev:

CObject * players[] = new CSpaceShip[MAX_PLAYERS];

Error: { expected

Är du 100 % säker på att det felet verkligen gäller den raden? Att det inte är ett följdfel pga underligheter på annat ställe? Till att börja med skulle jag noga kolla att alla mina parentespar verkligen matchar varandra och finns på rätt ställe om det var min kod. Ett sätt att prova är att avkommentera den raden och allt nedanför som beror av den definitionen.

Alpha IIMedlem sedan maj 20002 993 inlägg
#15

Har massivs med fel... :( Tänk vad mycket jobb det skulle bli m,ed ett så enkelt spel. Ska försöka mer i morgon. Eller läsa på lite mer om C++ i min bok..

PeWMedlem sedan juni 200010 432 inlägg
#16

Ta det lugnt.
Börja smått och bygg på spelet med komponenterna bit för bit istället, så kan du lättare isolera de brister som uppkommer.

135 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
132 ms — hämta tråd, inlägg och bilagor (db)