srand() , Array einer Klasse
-
Hallo!
In der 1. Klasse erstelle ich mit einer Zeile eine große Anzahl der 2. Klasse:
//Aufruf aus 1. Klasse myAnts=new ant[NUMBER_ANTS];Nun brauche ich in der 2. Klasse aber rand()!
Blöderweise wird für alle erzeugten Klassen der gleiche Zufallswert zurückgegeben!//Im Konstruktor der 2. Klasse position.setVector((double)rand()/RAND_MAX*PANEL_X,(double)rand()/RAND_MAX*PANEL_Y); direction.setVector((double)rand()/RAND_MAX*360.0);Nun habe ich srand(time(0)) schon an verschiedenen Stellen im Code probiert, leider erfolglos.
Ich dachte bis jetzt immer der Zufallsgenerator startet bei einem Wert (wofür man eben srand braucht), und gibt dann der Reihe nach Zahlen aus.
Anscheinend merkt sich der Zufallsgenerator aber nicht, dass er bereits die erste Zufallszahl in der Reihe zurückgegeben hat. Jedes mal im Konstruktor der 2. Klasse fängt er bei der gleichen Zufallszahl an. In der 2. Klasse aber srand(time(0)) aufrufen ist suboptimal, weil das ganze ja in weniger als 1s abläuft, und somit erst recht jedes Mal bei der gleichen Zahl gestartet wird und ich immer die gleichen Zufallszahlen erhalte.Irgendwelche Ideen wie ich das hinbekommen kann?
-
Erstmal solltest du
srandnur am Programmanfang hinsetzten und sonst nie wieder aufrufen und zudem solltest du C++-Casts statt C-Casts verwenden.
-
EOutOfResources schrieb:
Erstmal solltest du
srandnur am Programmanfang hinsetzten und sonst nie wieder aufrufen und zudem solltest du C++-Casts statt C-Casts verwenden.Ich habs in der Controller Klasse (oben als 1. Klasse bezeichnet) aufgerufen, diese wird nur ein einziges Mal erstellt.
//Aufruf aus 1. Klasse srand(time(0)); myAnts=new ant[NUMBER_ANTS];Leider bringt auch das nichts!
-
Vielleicht könntest du mal etwas mehr Code zeigen. Wenn die beiden Klassen nicht allzu gross sind könntest du diese vielleicht mal posten.
-
Ja klar, sind eh noch sehr kurz!
//1. Klasse #include "..\include\controller.h" #define NUMBER_ANTS 20 #define NUMBER_FOOD 50 controller::controller() { //ctor srand(time(0)); //HIER!!! SRAND myAnts=new ant[NUMBER_ANTS]; myFood=new food[NUMBER_FOOD]; } controller::~controller() { //dtor } void controller::drawTheSim(wxPaintDC *dc) { wxColor color; color.Set(255,0,0,255); dc->SetBrush(wxBrush(color)); dc->DrawRectangle(0,0,PANEL_X,PANEL_Y); for(int i=0;i<NUMBER_ANTS;i++) { myAnts[i].drawTheAnt(dc); } }//2. Klasse #include "..\include\ant.h" ant::ant() { //ctor antBrain=new ann(50,3); init(); /*DATEI DEBUG FILE *f=0; f=fopen("dbgOut.txt","a+"); fprintf(f,"ANT\n"); fclose(f); //ENDE DATEI DEBUG*/ } ant::~ant() { //dtor delete antBrain; } void ant::init() { //HIER!!! RAND AUFRUF position.setVector((double)rand()/RAND_MAX*PANEL_X, (double)rand()/RAND_MAX*PANEL_Y); direction.setVector((double)rand()/RAND_MAX*360.0); fullness=0; //DATEI DEBUG FILE *f=0; f=fopen("dbgOut.txt","a+"); fprintf(f,"%f / %f\n",position.getX(),position.getY()); fclose(f); //ENDE DATEI DEBUG //direction.setVector(rand()%PANEL_X, rand()%PANEL_Y); } void ant::drawTheAnt(wxPaintDC *dc) { dc->DrawLine(position.getX(), position.getY(), position.getX()+10*direction.getX(), position.getY()+10*direction.getY()); }
-
- Hier Fehlen die Deklarationen, die zeig uns bitte auch noch,
- Ich sehe hier keinen Grund, die Variablen auf dem Heap zu erzeugen, vielleicht erschließt sich mir das ja bei 1)
- #define für Konstanten ist nicht empfehlenswert. Benutze:
const unsigned NUMBER_ANTS = 20;
-
314159265358979 schrieb:
- Hier Fehlen die Deklarationen, die zeig uns bitte auch noch,
- Ich sehe hier keinen Grund, die Variablen auf dem Heap zu erzeugen, vielleicht erschließt sich mir das ja bei 1)
- #define für Konstanten ist nicht empfehlenswert. Benutze:
const unsigned NUMBER_ANTS = 20;Danke für die Hinweise, werde ich dann umsetzen!
Hier die Header Dateien:
#ifndef CONTROLLER_H #define CONTROLLER_H #include "..\include\ant.h" #include "..\include\food.h" #include "..\include\globalVar.h" class controller { public: controller(); virtual ~controller(); void drawTheSim(wxPaintDC *dc); protected: ant *myAnts; food *myFood; private: }; #endif // CONTROLLER_H#ifndef ANT_H #define ANT_H #include "..\include\ann.h" #include "..\include\vector2D.h" #include "..\include\globalVar.h" class ant { public: ant(); virtual ~ant(); void init(); void drawTheAnt(wxPaintDC *dc); protected: vector2D direction,position; double fullness; ann *antBrain; private: }; #endif // ANT_H
-
weiters verstehe ich nicht, warum sich das Programm beim Schließen aufhängt, falls ich im Controller Destructor die zuerst erstellten Variablen mit delete[] lösche:
delete[] myAnts; delete[] myFood;Bei C hab ich ja auch immer zuerst malloc und dann free gemacht, wenn ich ein dynamisches Array hatte!
-
Dann wirst du dabei wohl etwas falsch gemacht haben
. Ein erster offensichtlicher Fehler ist, dass du die Regel der großen Drei verletzt, die hier angebracht wäre.Du weißt, dass es dynamische Arrays als fertige Klasse (std::vector) gibt, bei der speichertechnisch nichts mehr schiefgehen kann? Dann bräuchtest du dich auch nicht mehr um Destruktor, Kopier-Konstruktor und Zuweisungsoperator zu kümmern.
-
SeppJ schrieb:
Dann wirst du dabei wohl etwas falsch gemacht haben
. Ein erster offensichtlicher Fehler ist, dass du die Regel der großen Drei verletzt, die hier angebracht wäre.Du weißt, dass es dynamische Arrays als fertige Klasse (std::vector) gibt, bei der speichertechnisch nichts mehr schiefgehen kann? Dann bräuchtest du dich auch nicht mehr um Destruktor, Kopier-Konstruktor und Zuweisungsoperator zu kümmern.
Vektoren kenn ich, bin halt noch etwas C mäßig am Weg.
Werd dann morgen die Arrays gegen std::vector austauschen, dann hat sich das Problem hoffentlich gelöst!Das mit dem srand hab ich jetzt so gelöst, nicht gerade elegant, aber es klappt:
srand(antAmount*time(0)); wobei mir antAmount angibt, wieviele Male der Ctor schon aufgerufen wurde.Regel der großen Drei???
-
-> Google
Copy-Ctor, Copy op =, Destruktor. Implementierst du einen der drei, solltest du die anderen beiden auch Implementieren.
-
Glutamat schrieb:
Regel der großen Drei???
Wenn einer der folgenden drei Methoden implementiert ist, sollten es auch die anderen zwei sein:
- Copy-Konstruktor
- Zuweisungsoperator
- Destruktor
-
Problem gefunden:
Irgendwo in den Untiefen einer von mir schon länger erstellten Klasse habe ich srand(time(0)) aufgerufen, und das hat mir das Problem beschert.Danke nochmal für eure Hilfe!