Instanz wird erzeugt, ohne dass der Konstruktor aufgerufen wird
-
hallo zusammen. ich habe vor einiger zeit ein buch über c++ zu ende gelesen und dachte mit, dass ich als übung ein kleines konsolenspiel programmieren könnte. doch jetzt bin ich auf ein wirklich seltsames problem gestoßen.
ich habe eine funktion, die instanzen für asteroiden erstellt, die man mit einem raumschiff abschießen kann (ich weiß, unschlagbares konzept). rein optisch funktioniert auch alles. um zu schauen, wieviele instanzen vorhanden sind habe ich einen zähler eingebaut, der statisch ist und beim aufruf des konstruktors hochzählt und beim destruktur runterzählt. selbst wenn ich die ausgabe ständig aktualisiere und sehe, wie neue asteroiden erzeugt werden ändert sich der zählstand nicht, sondern bleibt auf 0. (die ausgabe des zählstandes wird natürlich permanent aktualisiert)
was mir noch auffiel ist, dass in der zeile:
CAsteroid tempAsteroid(&render);
der name der instanz rot markiert ist. ich verwende msvc6 und visual assist x. rot werden normalerweise nur funktionen angezeigt, instanzen jedoch grau. ich habe auch geschaut, dass ich sicher keine funktion mit diesem name habe.
ich hoffe, jemand kann mir sagen, was hier schiefläuft. ich habe jetzt zwei tage lang jede zeile nochmal durchgeschaut und geändert. nichts hilft.
vielen dank schonmal
-
code
-
Vorweg: Ein bisschen Code schadet fast nie.

CAsteroid tempAsteroid(&render);Das sieht doch nach dem Aufruf eines benutzerdefinierten Konstruktors aus; und das ist sehr wohl ein Funktionsaufruf.
-
Ich geb ne runde Kristallkugeln *fg*
So kann dir keiner helfen^^
-
ich hoffe, der code wird auch als solcher angezeigt
void CGame::spawnAsteroids(void) { // drawarea ist eine instanz einer klasse, die für das rendern // verantwortlich ist CAsteroid tempAsteroid(&DrawArea); m_lAsteorid.push_back(tempAsteroid); }hier wird also ein asteroid erzeugt.
CAsteroid::CAsteroid(CDrawEngine* de) { // zähler für instanzen CAsteroid::m_instanceCntr++; // zeiger übergeben m_pDrawArea = de; // ein asteroid hat ein leben addLives(1); // einen zufälligen spawnpoint festlegen m_fPosX = (float)((rand() % (m_pDrawArea->m_screenWidth - 2))+ 1); m_fPosY = 1; m_pDrawArea->drawSprite(m_index, (int)(m_fPosX), (int)(m_fPosY)); }und hier noch ein ausschnitt aus der updatefunktion, die die asteroiden bewegt
if (m_lAsteorid.empty() == false) { // jeden asteroid abfragen for (Itr = m_lAsteorid.begin(); Itr != m_lAsteorid.end(); ++Itr) { // diese funktion bewegt den asteroid weiter (Itr)->updateAsteroid(); // wen der asteroid tot ist... if ((Itr)->isAlive() == false) // ...aus der liste entfernen Itr = m_lAsteorid.erase(Itr); } }und hier noch der destruktor des sprites
CAsteroid::~CAsteroid(void) { CAsteroid::m_instanceCntr--; m_pDrawArea->eraseSprite(m_fPosX, m_fPosY); }also wie schon gesagt, der zähler funktioniert nicht und wenn ich in den konstruktor etwas einbaue wie
cout << "Konstruktor aufgerufen";
dann erscheint auch das nicht. das programm schein meinen konstruktor einfach zu übersehen, obwohl alles richtig in der headerdatei angegeben ist.
-
und die Klassendefinition?
-
#ifndef ASTEROID_H #define ASTEROID_H #include "Sprite.h" class CAsteroid : public CSprite { public: CAsteroid(CDrawEngine* de); ~CAsteroid(void); void updateAsteroid(void); static int m_instanceCntr; private: bool checkCollision(int x, int y); }; #endifmeinst du das hier?
-
Schonmal ein komplettes rebuild gemacht?
-
sorry, da bin ich wohl noch zu sehr n neuling. was istn rebuild??

alles auseinandernehmen und neu zusammenbauen?
-
"CAsteroid::m_instanceCntr++;"
-> Nimm bei diesen Aufrufen mal den Klassenname und den Bereichsoperator weg, sodass daraus "m_instanceCntr++;" wird.
Zu deinem anderem Problem: Bist du dir sicher, dass du den Namespace "std" irgendwie zugänglich gemacht hast in der Implementationsdatei für den Konstruktor? Also über "using namespace std;" oder "using std::cout"?
-
was passiert, wenn ein CAsteroid kopiert wird, also z.B.:
CAsteroid asteroid1(&DrawArea); CAsteroid asteroid2(asteroid1);
-
habs gerade versucht, hat aber keinen unterschied gemacht. ich habe noch ein paar dinge geändert und anscheinend wurde nicht richtig erkannt, wann ein asteroid tot ist. er verschwand zwar richtig aus der console, jedoch schien seine instanz weiterzuleben. der zähler zählt jetzt also runter und ich bekomme einen negativen zählwert.
das ist jetzt wirklich seltsam, da der konstruktor ja zwangsläufig beim entstehen eines asteroiden aufgerufen werden muss.
-
also das peoblem kann jetzt nurnoch bei
m_instanceCntr++;
liegen. der konstruktor muss nämlich zwangsweise funktionieren, da sonst ein asteroid nicht einen zufälligen spawnpunkt hätte.
-
CAsteroid hat zwei Konstruktoren, nur einer davon ändert Wert von m_instanceCntr (und ob du nun m_instanceCntr oder CAsteroid::m_instanceCntr oder this->m_instanceCntr etc. schreibst, ist völlig irrelevant).
-
ich habe jetzt auf genau die selbe weise einen statischen zähler für CSprite instanzen gemacht, da CSprite ja die basisklasse eines asteroiden ist. und hier wird tatsächlich auch hochgezählt.
der konstruktor von CAsteroid muss aber wie schon gesagt aufgerufen werden, denn sonst würden die asteroiden nicht angezeigt werden, da der instanz der pointer auf die klasse zum rendern fehlen würde...
ich habe auch das hochzählen für die asteroidenklasse an jede nur erdenkliche stelle hingepackt. einmal sogar in eine funktion, die vom konstruktor aufgerufen wird. alles schient zu funktionieren, bis auf diese eine programmzeile, bei der man doch kaum etwas falsch machen kann.
wirklich seltsam.
-
Wie erzeugst du denn deine Asteroiden?
Ist die statische Varibale initialisiert?
/edit/
erste Frage nehme ich zurück. Hab es gerade entdeckt
-
das steht in der asteroid.cpp
int CAsteroid::sm_instanceCntr = 0;scheint ja auch zu funktionieren. der zähler steht wie gewollt zu beginn auf 0.
-
Hm, verzwicktes Problemchen.

Was passiert wenn du die Syntax leicht abänderst, also statt
CAsteroid tempAsteroid(&render);CAsteroid tempAsteroid = CAsteroid(&render);verwendest?
Nur als Test, ob zumindest die rote Kennzeichnung als Funktion verschwindet... *grübel*
-
leider keine besserung. die rote markierung ist übrigends doch so richtig. ich hab es nochmal an einem einfachen beispiel getestet. wenn sich jemand wundert, warum manche namen sich im code ändern, dann liegt das daran, dass ich einiges zur bessren übersicht geändert habe. an der schreibweise kann das problem aber kaum liegen, sonst würde ja der compiler etwas anzeigen.
ich glaube ich werds wohl so hinnehmen müssen. solange der rest in den funktionen wie erwartet funktioniert ist das spiel ja funktionsfähig.
danke für euer bemühen

-
Ah, jetzt ...
Du erzeugst ja ein Objekt, dass nicht lange erhalten bleibt. Das Schieben in den Container wird ja mit dem Copy-Konstruktor erledigt. D.h. das Objekt wird gleich wieder gelöscht. Könnte es daran liegen?
Wenn ja, hätte camper das Problem eigentlich schon erwähnt.

/edit/
Der negative Zähler lässt sich dadurch erklären, dass der Destruktor die Objekte im Container runterzählt, die der Copy-Konstruktor nicht hochgezählt hat.Wenn es das auch nicht ist, gebe ich auch auf.

-
hmmm. erscheint mir nicht schlüssig. der zähler ist ja statisch und bleibt somit erhalten selbst wenn die instanz zerstört wird.
außerdem dürfte dann auch nicht das herunterzählen funktionieren.