Trädvy Permalänk
Medlem
Registrerad
Feb 2005

c++ lyder inte mig

Hej.
Jag har 2 frågor.

1.

Varför funkar det när jag skriver

getLevel()->getModel()->getPlayer()->collision(getSpace());

men inte när jag skriver

getModel()->getPlayer()->collision(getSpace());

//det är inte samma getModel utan den länst ner ska vara intern i klassen men ska ha samma objekt, men verkar itne funka.

Jag skickar ju med model när jag skapar objektet med samma getModel som längst upp så jag kan inte se hur det skulle göra någon skillnad.

addObjectActive(SimpleSolid(temp,0,0,this,getModel()));

2.
Om jag har en funktion i en klass

virtual void Update_Object(int pos){} som ser ut såhär

och en klass som ärver den klassen och har en annan definition på funktionen

void SimpleSolid::Update_Object(int pos){
getLevel()->getModel()->getPlayer()->collision(getSpace());

}

borde inte den senare funka då, nu går programmet aldrig in i funktionen, men tar jag bort virtual och lägger in vad den ska göra i underklassen så funkar det, så varför vill min överklass inte köra över den undra klassen.

Trädvy Permalänk
Medlem
Plats
Lund
Registrerad
Jan 2003

Det funkar inte för att du inte kodat korrekt.. det är dessutom rätt svårt att se vart felet finns om man inte ens vet hur dina klasser är implementerade.

Du ger väldigt lite information för att lösa problemet i vart fall!

i5 2500k, GTX770SLI, 8GB RAM

Trädvy Permalänk
Medlem
Registrerad
Feb 2005
Trädvy Permalänk
Hedersmedlem
Plats
Linköping
Registrerad
Apr 2004

Re: c++ lyder inte mig

Citat:

Ursprungligen inskrivet av hawy
Varför funkar det när jag skriver

getLevel()->getModel()->getPlayer()->collision(getSpace());

men inte när jag skriver

getModel()->getPlayer()->collision(getSpace());

Vad är det som inte fungerar? Vad säger kompilatorn?

Citat:

Ursprungligen inskrivet av hawy
Om jag har en funktion i en klass

virtual void Update_Object(int pos){} som ser ut såhär

och en klass som ärver den klassen och har en annan definition på funktionen

void SimpleSolid::Update_Object(int pos){
getLevel()->getModel()->getPlayer()->collision(getSpace());

}

borde inte den senare funka då, nu går programmet aldrig in i funktionen, men tar jag bort virtual och lägger in vad den ska göra i underklassen så funkar det, så varför vill min överklass inte köra över den undra klassen.

Vilken funktion går den aldrig in i? Skälet till att använda "virtual" från början är ju att man vill att underklassens funktion skall köras istället för basklassens.

Trädvy Permalänk
Medlem
Plats
Linköping
Registrerad
Jun 2007
Citat:

Ursprungligen inskrivet av hawy
okey, här är klasserna http://data.fuskbugg.se/skalman01/-kod.rar

I koden du skickat anropar du aldrig Update_Objects, och funktionerna addObject och addObjectActive är heller inte definierade någonstans. Om du skickar rätt kod så är det nog enklare att få hjälp

Trädvy Permalänk
Medlem
Registrerad
Feb 2005

ja alltså den går aldrig in i underfunktionen, dne händer inget liksom.

http://data.fuskbugg.se/skalman01/kod2.rar

Lite mer kod

Trädvy Permalänk
Medlem
Plats
Linköping
Registrerad
Jun 2007

Ditt problem är slicing. Du lagrar instanser av Active_objects i en array, Active_objects activeobj[100] i Levels-klassen. Du kan tänka på detta som att du har 100 lådor, där varje låda får plats med ett Active_object. Sen försöker du lägga i en SimpleSolid en av lådorna. En SimpleSolid ärver ju av Active_object, så på ett sätt så är en SimpleSolid ett Active_object. Men problemet uppstår nu i att ett SimpleSolid-objekt inte bara är ett Active_object, utan Active_object-delen är bara en del av SimpleSolid. Detta struntar dock C++ i, och trycker glatt ner SimpleSolid-objektet i en Active_object-låda, vilket är ungefär som att försöka trycka ner ett fyrkantigt block i ett runt hål. Det går om man tar i tillräckligt mycket, men delar av blocket kommer inte med. Så eftersom alla instanser i activeobj-arrayen är Active_objects så är det ju inte så konstigt att det blir Active_objects Update_Object som anropas istället för SimpleSolids Update_Object.

Problemet uppstår egentligen redan när du skickar SimpleSolid-instansen till addObjectActive, som tar emot ett Active_object. För att polymorphismen ska fungera i C++ så måste du därför skicka runt instanserna som pekare eller referenser, och ska du lagra dem i en lista så är det pekare som gäller.

Förresten, varför använder du arrayer för att lagra objekt? Du programmerar ju C++, så det skulle vara mycket bättre att använda std::vector eller std::list istället. Nu begränsar du ju antalet Object till 100 t.ex., vilket är ganska onödigt, och dessutom slösar bort minne om du inte använder så många Object.

Angående getModel-problemet du hade så ser jag inte varför det inte skulle fungera. Vad får du för fel från kompilatorn?

Trädvy Permalänk
Medlem
Registrerad
Feb 2005

Okey, tack så mycket.

Så om jag alltså skulle göra mina arrayer till arrayer med pekare så skulle det funka?
Ska kolla upp listor, är självklart smidigare än arrayer.

Angående get Model så ger kompilatorn inga fel men programmet kraschar så fint

edit//jepp nu funkar det

Trädvy Permalänk
Medlem
Registrerad
Dec 2004

En vanlig tumregel som jag brukar använda är att objekt med polymorfism endast bör behandlas med pekare (referenser bör också fungera, men då dem används på ett sätt som är för likt "vanliga" variablar så finns det en mycket större risk för fel).

Så, i detta fall så vill man ha:

Active_objects* activeobj[100];

Alternativt, per perost's förslag:

vector<Active_objects*> activeobj;

eller

list<Active_objects*> activeobj;

Observera att i båda fallen måste man se till sköta allokeringen/deallokeringen av minnet manuellt (såvidda man inte använder någon form av shared_ptr/auto_ptr).

"Nothing is impossible because impossible itself says I M Possible..."

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Aug 2007

C++ lyder dig. Det är bara du som gör fel.