Wie variable anzahl an Instanzen eines structs zur Laufzeit erstellen?

C

Crymes

Guest
Hallo, ich möchte beliebige anzahl an Bällen erstellen, mein struct sieht os aus:
Code:
[FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]struct[/SIZE][/FONT][/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] kugel[/SIZE][/FONT]
[SIZE=2][FONT=Consolas]{[/FONT][/SIZE]
[/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]float[/SIZE][/FONT][/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] position[2];[/SIZE][/FONT]
[/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]float[/SIZE][/FONT][/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] geschwindigkeit[2]; [/SIZE][/FONT]
[/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]float[/SIZE][/FONT][/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] radius;[/SIZE][/FONT]
[SIZE=2][FONT=Consolas]};[/FONT][/SIZE]
[/SIZE][/FONT]

Ich habe schon gegoogelt, ich brauche soweit ich gelesen hab einen variablen array, z.B. ball[nummer].
Wo muss aber jetzt das new hin und wie handle ich das wieder mit dem löschen?

Würde so eine Schleife gehen:

for(x=0;x<nummer;x++)
{
ball[x] = new(kugel)
}

Oder hab ich das falsch verstanden?
 
Kleines Beispiel
Code:
struct Ball
{
    int posX;
    int posY;
};

// erzeugt dynamisch 10 Bälle
Ball *pBaelle = new Ball[10];

// Zugriff auf den 2. Ball (Index beginnt bei 0)
pBaelle[1].posX = 1;
pBaelle[1].posY = 1;

// Löschen (mit [], da es sich um ein Array handelt)
delete[] pBaelle;
 
Wenn ich jetzt in ner Funktion damit rechnen will, zeige ich dann mit einem Pointer auf einen Pointer?
 
Bei dynamischen Objekten empfiehlt es sich aus den Instanzen eine Liste zu machen. Das Problem was auftritt wenn du einenen Array anlegst, du kannst nicht einfach Objekte löschen. Ein Ball der bspw. auf einem Spielfeld ist bleibt nicht zwingend auf dem Spielfeld und muss ggf. "zerstört" werden.
Daher nimmst du deine Struktur und setzt ein oder 2 neue pointer. Die Pointer zeigen dann immer auf das nächste oder vorhergende Objekt. Nennt sich dann verkettete Liste. Du musst dann nurnoch das erste Objekt in der Liste speichern und kannst von dort aus die gesamte Liste durchgehen und deine Attribute setzen. Ein neues Element hinzufügen ist keine Problem, eines entfernen auch nicht. Mit einem new [] ist das so ohne weiteres nicht leicht zu realisieren.

Ein kleiner Hinweis am Rande: der Befehl new ist C++ Sprachraum während struct C Sprachraum ist. Beides vermischen ist kein guter Stil und kann unter anderem die Portierbarkeit deines Codes einschränken. Daher entweder C++ class nehmen oder malloc() für C. ;)
 
Ein kleiner Hinweis am Rande: der Befehl new ist C++ Sprachraum während struct C Sprachraum ist. Beides vermischen ist kein guter Stil und kann unter anderem die Portierbarkeit deines Codes einschränken. Daher entweder C++ class nehmen oder malloc() für C. ;)
Nein. In C++ ist struct dasselbe wie class, nur das per Default alle Attribute bei struct public sind.

Code:
struct BlaStruct
{
    int x;
    void methode();
};

class BlaClass
{
public:
    int x;
    void methode();
};
Beide Objekte sind in C++ vollkommen äquivalent.


Wenn ich jetzt in ner Funktion damit rechnen will, zeige ich dann mit einem Pointer auf einen Pointer?
Kannst du machen

Code:
void funktion(Ball *pBall)
{
   // whatever...
}

void multifunktion(Ball *pBaelle, int anzahl)
{
   for (int i = 0; i < anzahl; ++i)
   {
       pBaelle[i].posX = i;
       pBaelle[i].posY = (i + 1) / 2;
   }
}



Ball *pBaelle = new Ball[10];
// Aufruf für einen Ball (hier muss mittels des Adressoperators & die Adresse übergeben werden, da pBall[0] kein Zeiger mehr ist)
funktion(&pBaelle[0]);

// Aufruf für das gesamte Array
multifunktion(pBaelle, 10);
 
Zuletzt bearbeitet:
Es soll darauf hinaus, dass ich bei dem Druck eioner Taste einen Bal hinzufüg und bei dem Druck auf eine andere einen löschen kann.
Ich werde das mit den Listen ma nachschauen.
 
Dann sind Listen genau das richtige weil die Anzahl Bälle variabel ist und du sonst immer ein Array brauchst mit einer statischen Anzahl Felder.
 
Kann mir jemand ne gute Quelle nennen, wo die Listen gut erklärt sind?:hail:
 
Wenn ich jetzt in ner Funktion damit rechnen will, zeige ich dann mit einem Pointer auf einen Pointer?

Kannst du machen, ist aber nicht notwendig und verwirrt eher. Es reicht, wenn du den Pointer direkt übergibst. Ein Pointer ist ja nichts anderes als eine bestimmte Adresse im Speicher, also eine natürliche Zahl, die du als Wert übergeben kannst. Einen Pointer auf einen Pointer bräuchtest du nur, wenn du was daran ändern willst, wo der Pointer hin zeigt.
Dieses Beispiel verdeutlicht den Zusammenhang(einfach mal ausprobieren):
Code:
#include <iostream>
using namespace std;
int* array; // wird dynamisch angelegt
void f(int* ptr)
{
  *ptr = 1234;
  cout << ptr << endl << array <<endl;
}
int main(void)
{
   array = new int[3];
   array[0] = 0;
   cout << array;
   f(array);
   return 0;
}
 
Zuletzt bearbeitet:
Ich schau mir das grad mit dem vector Template an, da ist ja eigentlich alles, was ich brauche schon vordefiniert.
Hab aber grad nicht so viel Zeit, da ich mit 2 Vorträgen ein bisschen spät dran bin :what:.
 
Kann mir jemand sagen, warum bei folgender Zeile der Modulu Operator nicht funktioniert? (Ich will aus dem Container vector(ball) ein zufälliges element löschen)

ball.erase((rand() % ball.end()));

 
end() liefert einen Iterator und keine Zahl, daher klappt das nicht. Die Anzahl der Elemente erhälst du mit size().
 
ballliste.erase(rand() % ballliste.size());

Dann kommt der Fehler:
error C2664: 'std::_Vector_iterator<_Myvec> std::vector<_Ty>::erase(std::_Vector_const_iterator<_Myvec>)': Konvertierung des Parameters 1 von 'unsigned int' in 'std::_Vector_const_iterator<_Myvec>' nicht möglich

Ist es hier vll. ratsam, eine funktion für dien zufallszahlern zu Schreiebn? Dann hätt ich halt wieder eine unnötige Variable mehr:huh:
 
Top, der braucht für erase einen Iterator, das habe ich grade übersehen -.-

Versuch das mal:
Code:
Vector v;
// ...

// Position bestimmen
size_type pos = rand() % v.size();
// löschen
v.erase(v.begin() + pos);
 
size_type wird rot unterstrichen, is bei ihm nicht definiert.
Das würde gehen:

int x = rand() % ballliste.size();
ballliste.erase(ballliste.begin() + x );

Dann hab ich halt wieder eine überflüssige Variable.

Edit: Wenn ich es folgendermaßen mache, dann können doch alle Elemente des vectors ausgewählt werden, oder?

unsignedshortint zufallszahl = rand() % (ballliste.size()+1);
ballliste.erase(ballliste.begin() + zufallszahl );


Edit 2: Habs nachgerechnet, ohne das +1 stimmts, sonst würde er ein Element zu viel im vector vermuten, richtig?
 
Zuletzt bearbeitet:
Ich dachte, size_type wäre ein typedef wie size_t. Normalerweise zeigt das auf unsigned int, daher ist das ok.
 
Das ist jetzt meine fertige Lösch -Funktion:

Code:
[FONT=Consolas][SIZE=2][COLOR=#008000][FONT=Consolas][SIZE=2][COLOR=#008000][FONT=Consolas][SIZE=2][COLOR=#008000]
//funktion Ball entfernen[/SIZE][/FONT][/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]void[/SIZE][/FONT][/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] deleteball()
{
[/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]unsigned[/SIZE][/FONT][/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]short[/SIZE][/FONT][/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]int[/SIZE][/FONT][/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] zufallszahl = ballliste.size(); 
[/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]if[/SIZE][/FONT][/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2](zufallszahl > 0)
{
zufallszahl = rand() % zufallszahl; 
ballliste.erase(ballliste.begin() + zufallszahl);
}
}
[/SIZE][/FONT][/SIZE][/FONT]

Sollte fehlerfrei funktionieren.
Die addball Funktion wird deutlich komplizierter, da ich erst npoch prüfen muss, wo auf dem Bildschirm genug Platz für einen neuen Ball ist.:daumen:
 
Zurück