Vektor per Schleife mit Klassenobjekten füllen [gelöst]
-
Hallo, ich bin neu hier in der Community, fange gerade mit C++ an und habe eine Frage bezüglich des Befüllens von Vektoren mit Objekten aus einer Klasse. Mein Problem ist, dass ich eine Fehlermeldung erhalte.
for (int i = 0; i < 10; ++i) { ENEMY pers[i]; pers[i].AddEnemy(1, 1); }
ENEMY ist die Klasse, pers soll das Objekt sein und AddEnemy die Methode. Bezüglich der Zeile … ENEMY pers[i]; … erhalte ich folgende Fehlermeldung für die Zählervariable i :
Ausdruck wurde nicht zu einer Konstanten ausgewertet bzw. der Ausdruck muss einen Konstantenwert aufweisen.
Danke für Eure Hilfe!
-
@Kloeterkong sagte in Vektor per Schleife mit Klassenobjekten füllen:
ENEMY ist die Klasse, pers soll das Objekt sein und AddEnemy die Methode.
... und wo ist der
std::vector<>
??@Kloeterkong sagte in Vektor per Schleife mit Klassenobjekten füllen:
Bezüglich der Zeile … ENEMY pers[i]; … erhalte ich folgende Fehlermeldung für die Zählervariable i:
Ausdruck wurde nicht zu einer Konstanten ausgewertet bzw. der Ausdruck muss einen Konstantenwert aufweisen.
Weißt Du was ein Array ist?
-
@Kloeterkong sagte in Vektor per Schleife mit Klassenobjekten füllen:
ENEMY pers[i];
Was soll das bedeuten? Der Compiler denkt, du möchtest ein Array von ENEMY anlegen. Das geht aber nur mit einer konstanten Länge und nicht mit einer variablen Länge wie i. Was willst du hier erreichen?
-
Hallo, das geht aber schnell - danke schon einmal für die schnellen Rückinfos. Ich versuche es mal anders zu erklären - habe verstanden das man aus dem Code-Schnipsel nichts erkennen kann - sorry. Hier mal ein Code, welcher 4 Zeilen ausgibt. Einmal über die Darstellungsmethode der Klasse Person, einmal direkt über die Darstellungsmethode der Gruppe:
#include "pch.h"
#include <iostream>
#include <string>
#include <vector>
#include <windows.h>using std::cout;
using std::cin;
using std::string;
using std::endl;class Person
{
private:
string Geschlecht;
string Name;
float Abschluss;public:
void add(string name, string geschlecht, float note);
void ausg();
};class Group
{
private:
std::vector<Person> Gruppe;public:
void addgroup(Person pe);
void printgroup();
};void Person::add(string name, string geschlecht, float note)
{
Geschlecht = geschlecht;
Name = name;
Abschluss = note;
}void Group::addgroup(Person pe1)
{
Gruppe.push_back(pe1);
}void Group::printgroup()
{
for (size_t i = 0; i < Gruppe.size(); ++i)
{
Gruppe[i].ausg();
}
}void Person::ausg()
{
cout << "Person: " << Geschlecht << " " << Name << " ,Note: " << Abschluss << endl;
}int main()
{
Person pers1;
Person pers2;
Group gruppe1;pers1.add("Max", "Mustermann", 2.0);
pers1.ausg();
pers2.add("Hans", "Meier", 2.2);
pers2.ausg();gruppe1.addgroup(pers1);
gruppe1.addgroup(pers2);
gruppe1.printgroup();Sleep(100000);
}
Mein Ziel soll sein, dass ich die Objekte des Verktors gerne über eine Schleife einlesen lasse und nicht wie im Beispiel explizit mit pers1, pers2 oder gruppe1 … deswegen die Idee mit der Schleife.
-
Ich sehe gerade, der Quelltext ist nicht formatiert, da arbeite ich natürlich dran wenn ich sowas hier hereinstelle, danke fürs Verständnis
-
Formatieren geht mit ``` vor und nach deinem Code oder mit dem
</>
-Button.
-
Dann nochmal anständig …
#include "pch.h" #include <iostream> #include <string> #include <vector> #include <windows.h> using std::cout; using std::cin; using std::string; using std::endl; class Person { private: string Geschlecht; string Name; float Abschluss; public: void add(string name, string geschlecht, float note); void ausg(); }; class Group { private: std::vector<Person> Gruppe; public: void addgroup(Person pe); void printgroup(); }; void Person::add(string name, string geschlecht, float note) { Geschlecht = geschlecht; Name = name; Abschluss = note; } void Group::addgroup(Person pe1) { Gruppe.push_back(pe1); } void Group::printgroup() { for (size_t i = 0; i < Gruppe.size(); ++i) { Gruppe[i].ausg(); } } void Person::ausg() { cout << "Person: " << Geschlecht << " " << Name << " ,Note: " << Abschluss << endl; } int main() { Person pers1; Person pers2; Group gruppe1; pers1.add("Max", "Mustermann", 2.0); pers1.ausg(); pers2.add("Hans", "Meier", 2.2); pers2.ausg(); gruppe1.addgroup(pers1); gruppe1.addgroup(pers2); gruppe1.printgroup(); Sleep(100000); }
-
Also erstmal verwirrt dein Naming. Wenn du von einer Personen den Namen setzt, nennst du das "add"?! Add heiß hinzufügen/addieren. Dein
add
setzt aber die Daten.Bei der Gruppe ähnlich.
addgroup
fügt nicht eine Gruppe hinzu, sondern eine Person. Nenne es dochaddperson
. Oder lass deine Gruppenklasse ganz weg, es handelt sich doch eigentlich nur um einenstd::vector<Person>
.Wenn du in einer Schleife der Gruppe n Personen hinzufügen willst, dann:
for (auto i = 0; i < 10; ++i) { Person p; gruppe1.addgroup(p); }
Aber beachte meinen Kommentar zum verwirrenden Namen
addgroup
.Edit: du kannst deinen ersten Beitrag auch bearbeiten über die drei Punkte rechts neben dem "Zitieren"-Link.
-
Noch 3 Kommentare:
- willst du wirklich die vielen using... nutzen? Ich würde eher davon abraten.
- Das hier:
for (size_t i = 0; i < Gruppe.size(); ++i) { Gruppe[i].ausg(); }
kannst du besser schreiben:
for (const auto &person : gruppe) { person.ausg(); }
Beachte insbesondere, dass du hier keinen Zähler
i
brauchst, wenn du über alle Elemente loopen willst. Das ist weniger fehleranfällig und leichter lesbar.
Statt "Für alle Zahleni
von 0 bis einen weniger als Gruppenlänge mach XY" liest sich das als "Für jede Personperson
aus der Gruppe mach XY".-
Du scheinst allgemein weder
const
noch Referenzenconst &
zu nutzen. Kommt vielleicht noch später beim Lernen. Aktuell erzeugst du relativ viele Kopien, die vermeidbar wären. -
(von 3 ;-)) allgemein nutzt man den
operator<<
für die Ausgabe statt einerausg()
-Funktion. Aber da du bestimmt noch nicht weißt, wie das geht, ist das auch ne Info für später. -
Ich würde dir noch raten, Variablen und Funktionen mit Kleinbuchstaben und Klassen mit Großbuchstaben zu beginnen. Also
Gruppe
sollte eine Klasse sein, währendgruppe
die Variable wäre. -
Und das Deutsch/Englisch-Gemisch macht es nicht besser. Du hast eine Klasse
Group
und eine VariableGruppe
. Entscheide dich für eine Sprache (Englisch, wenn möglich - nur wenn es mal irgendwelche Spezialbegriffe aus dem Anwendungsbereich gibt, die es so nicht direkt in EN gibt, kann man einzelne deutschsprachige Namen behalten).
-
Danke, jetzt habe ich es so einigermaßen kapiert und klappt jetzt auch. Die using´s habe ich durch
using namespace std;
ersetzt und ich hoffe das mitconst
undconst &
kommt noch, genauso wie der sichere Umgang mit Namenskoventionen … wenn man sowas im Selbststudium und dicken Wälzern neben sich versucht zu lernen verzweifelt man ab und an …. positiver Effekt allerdings, man vertieft das, was man schon kann, auch wenn es noch sehr wenig ist …. aber Übung macht ja bekanntlich den Meister ...Vielen Dank!!!!
-
Ich habe ja jede Menge Abschlüsse, aber noch keinen davon konnte ich als
float
ausdrücken...(Oder die Moral dahinter: Wenn man stets versucht, alles möglichst perfekt zu modellieren - auch und gerade den einfachen Kinderkram - dann fallen einem später die schwierigen Datenmodelle viel leichter)
-
Hallo, das ist jetzt meine Anfänger-Lösung ….
srand((unsigned)time(NULL)); // Zufallsgenerator initialisieren. for (auto z = 0; z < 30; ++z) { int zufall1 = rand() % 120 + 1; int zufall2 = rand() % 30 + 1; int zufall3 = rand() % 100 + 1; ENEMY Gegner("Gnom", zufall1, zufall2, zufall3); Armee.push_back(Gegner); }
Das Objekt Gegner der Klasse ENEMY erhält bei der Erstellung bereits über den Konstruktor gewisse Eigenschaften. Armee ist der Vektor.
DANKE für Eure Hilfen und Hinweise!
Gegen Verbesserungsvorschläge habe ich natürlich nichts ...
-
for (auto z = 0; z < 30; ++z) { int zufall1 = rand() % 120 + 1; int zufall2 = rand() % 30 + 1; int zufall3 = rand() % 100 + 1; Armee.emplace_back( "Gnom", zufall1, zufall2, zufall3 ); }
Mit "emplace_back" hast du den Vorteil, dass das Objekt vom Typ "ENEMY" direkt im vector erzeugt wird, anstatt es erst zu erzeugen und dann zu kopieren. Du übergibst einfach nur die Konstruktor-Parameter an die "emplace_back"-Funktion.
Weitere Verbesserungsvorschläge:
- aussagekräftigere Variablennamen als "Zufall1", etc.
- bei Zählschleifen kann man sich ruhig eine nrichtigen Typ gönnen, anstatt es durch "auto" zu erschlagen. In deinem Fall verwendest du "z" nicht weiter, daher ist es egal, aber ich finde es persönlich besser, in dem Fall eben z.B. "unsigned" zu verwenden, wenn du nur im positiven ganzzahligen Bereich arbeitest.
- Die oberen Grenzwerte für deine Zufallszahlen ( 120, 30, 100 ) könntest du in Konstanten packen, die aussagekräftige Namen haben. Z.B. "MaxDexterity" oder, was auch immer die bedeuten.
-
@Kloeterkong sagte in Vektor per Schleife mit Klassenobjekten füllen [gelöst]:
Gegen Verbesserungsvorschläge habe ich natürlich nichts
Geschlecht sollte kein string sein, sondern ein enum. Du hast eine public Methode 'add' wo jeder bei Geschlecht eintragen kann was er will ('Mann', 'männlich' 'm',...).
Wenn du dann z.B. mal alle Männer finden sollst, hast du direkt ein Problem.
-
@Jockelx sagte in Vektor per Schleife mit Klassenobjekten füllen [gelöst]:
@Kloeterkong sagte in Vektor per Schleife mit Klassenobjekten füllen [gelöst]:
Gegen Verbesserungsvorschläge habe ich natürlich nichts
Geschlecht sollte kein string sein, sondern ein enum. Du hast eine public Methode 'add' wo jeder bei Geschlecht eintragen kann was er will ('Mann', 'männlich' 'm',...).
Wenn du dann z.B. mal alle Männer finden sollst, hast du direkt ein Problem.Noch besser wäre, gar keine festen Attribute zu haben, sondern eine flexible Liste von Attributbeschreibungen und zugehörigen Werten. Nicht jede Person auf der Welt wird über die gleichen Attribute beschrieben; hat alle Attribute, die du für wichtig hältst; oder du kennst nicht alle ihre Attribute.
Attribut Wert Vorname Max Nachname Mustermann Lieblingsfarbe blau Anzahl Finger 9 Das ist aber ziemlich philosophisch zur Datenmodellierung und hilft dir weniger beim Erlernen von C++.
-
@Jockelx sagte in Vektor per Schleife mit Klassenobjekten füllen [gelöst]:
Geschlecht sollte kein string sein, sondern ein enum.
Oha. Darf man sowas heutzutage noch vorschlagen, ohne dafür einen Shitstorm zu ernten? Was, wenn du ein Geschlecht vergessen hast? Oder willst du ein enum { w, m, d, andere, keineAngabe } machen? Wahrscheinlich würde ich versuchen, auf dieses Attribut zu verzichten. Einfach weil es nur Ärger macht. Irgendjemand, und wenn es nur ein Kolleg*in ist, der/die den Code liest, wird sich beleidigt fühlen.
-
@wob sagte in Vektor per Schleife mit Klassenobjekten füllen [gelöst]:
@Jockelx sagte in Vektor per Schleife mit Klassenobjekten füllen [gelöst]:
Geschlecht sollte kein string sein, sondern ein enum.
Oha. Darf man sowas heutzutage noch vorschlagen, ohne dafür einen Shitstorm zu ernten? Was, wenn du ein Geschlecht vergessen hast? Oder willst du ein enum { w, m, d, andere, keineAngabe } machen? Wahrscheinlich würde ich versuchen, auf dieses Attribut zu verzichten. Einfach weil es nur Ärger macht. Irgendjemand, und wenn es nur ein Kolleg*in ist, der/die den Code liest, wird sich beleidigt fühlen.
Das ist Anwendungsspezifisch.
- Die Mitgliederliste deines Buchclubs: Warum fragst du überhaupt?
- Deine Wahlumfrage: Wichtiges Gruppierungskriterium, das nicht fehlen darf, und wo es hauptsächlich auf die Selbstwahrnehmung des Befragten ankommt.
- Deine medizinische Humanstudie zur Wirkung eines neuen Medikaments: Frag gar nicht erst, sondern nimm gleich eine Blutprobe.
-
@wob sagte in Vektor per Schleife mit Klassenobjekten füllen [gelöst]:
Oha. Darf man sowas heutzutage noch vorschlagen, ohne dafür einen Shitstorm zu ernten?
Sicher darf man das.
Ich kann mich nicht erinnern mich jemals irgendwo registriert (oder was auch immer) zu haben und bei "Geschlecht" dann keine Combobox, sondern Freitext ausfüllen zu müssen.
-
@wob sagte in Vektor per Schleife mit Klassenobjekten füllen [gelöst]:
@Jockelx sagte in Vektor per Schleife mit Klassenobjekten füllen [gelöst]:
Geschlecht sollte kein string sein, sondern ein enum.
Oha. Darf man sowas heutzutage noch vorschlagen, ohne dafür einen Shitstorm zu ernten? Was, wenn du ein Geschlecht vergessen hast? Oder willst du ein enum { w, m, d, andere, keineAngabe } machen? Wahrscheinlich würde ich versuchen, auf dieses Attribut zu verzichten. Einfach weil es nur Ärger macht. Irgendjemand, und wenn es nur ein Kolleg*in ist, der/die den Code liest, wird sich beleidigt fühlen.
Unerheblich wer sich beleidigt fühlt. Rein rechtlich ist glaube "männlich, weiblich, diverse" absolut in Ordnung. Meine ich mal gelesen zu haben. Und nur die Rechtslage ist maßgeblich. Und das lässt sich prima durch ein enum erschlagen.