Unterschied zwischen enum & struct
-
Kann bitte jemand einem Anfänger wie mir die Unterschiede zwischen enum und struct erklären?
z.B.:
enum Zahlen {eins, zwei, drei}
und
struct Zahlen {int eins, int zwei, int drei}
Ich kann wenn überhaupt erkennen, dass in struct die Variablen schon initialisiert werden (müssen ?).
Ich bedanke mich im Vorraus.
-
ein enum ist ein Aufzählungstyp, das heißt für das Beispiel
enum Zahlen {eins, zwei, drei}
wenn du eine Variable vom Typ Zahlen erzeugst, dann kann diesen den Wert "eins", "zwei" oder "drei" annehmen.
Zahlen eineZahl = eins; Zahlen nochEIneZahl = zwei;
struct Zahlen {int eins, int zwei, int drei}
Dies ist ein Typ, der drei Member beinhaltet. Diese heißen "eins", "zwei" und "drei" und sind jeweils von Typ int.
Zahlen meineZahlen; meineZahlen.eins = 55; meineZahlen.zwei = 444; meineZahlen.drei = -13;
-
Ok, das hab ich verstanden, danke
Aber ist das der einzige Unterschied?
Und ?muss? jede Variable in einem struct initialisiert werden?EDIT: Wie kann ich einen struct samt Unterklassen ausgeben? (Oder muss jeder einzeln ausgegeben werden?)
Als kleines Bsp.:
#include<iostream> #include<string> using namespace std; struct Material { string Name; double Wert; int Gewicht; }; int main() { Material Silber; Silber.Name = "Silber"; Silber.Wert = 1014.03; Silber.Gewicht = 1; Material Gold; Gold.Name = "Gold"; Gold.Wert = 43578.79; Gold.Gewicht = 1; cout << Silber.Name; //... cin.get(); return 0; }
Wobei man dieses
Material Gold; Gold.Name = "Gold";
mit Sicherheit umgehen kann, oder nicht?
-
Eigentlich hat eine Klasse und eine Enumeration nicht so viel am Hut.
Eine Enumeration nimmst du, wenn es für etwas nur eine ganz bestimmte Menge an möglichen Werten gibt, wie zum Beispiel Geschlecht:
enum sex { male, female };
Eine Klasse (
class
oderstruct
, spielt keine Rolle) ist zwar, wie eine Enumeration, ein eigens erstellter Datentyp, allerdings führt ein Objekt einer Klasse Aufgaben aus. Ein Objekt einer Enumeration oder ein Enumerator kann keine Aufgaben ausführen. Du kannst nicht sagenfemale.geh_einkaufen()
. Dazu brauchst du schon eine Klasse:enum sex { male, female }; class Person { private: sex s; public: void geh_einkaufen() { // Einkauf wird erledigt. } }; Person Hans; Hans.geh_einkaufen();
Deswegen ist die Frage nach Unterschieden ein bisschen merkwürdig. Eine geeignete Frage wäre wenn dann, was der Unterschied zwischen struct/class/union ist.
-
Okidoki, auch nochmal bissel rumgegoogelt wegen unterschied class und struct.
--> Ist verstanden
Mit Unions befasse ich mich später, sobald sie in meiner Lektüre erläutert werden.
Das mit der Initialisierung hat sich von selbst erledigt.Bleibt nur noch die Frage, ob und wie ich ein struct samt unterklassen wiedergeben kann, quasi als Tabelle? (s.o.)
-
Enums sind doch immer Ints und werden damit auch gerne für den Enum-Hack verwendet, oder? So spart man sich z.B. ein #define MAX 42 für irgendwelche Arraygrößen und der Compiler kann aufgrund des Eintrages in der Symboltabelle, gleich einen Namen zum Fehler ausgeben und man muss nicht raten wo die 42 auf einmal herkommt.
-
xStrykex schrieb:
Okidoki, auch nochmal bissel rumgegoogelt wegen unterschied class und struct.
--> Ist verstandenSicher? Oft wird das nämlich falsch erklärt. Einziger Unterschied ist die Defaultsichtbarkeit (public/private). Eventuell kann man noch sagen, dass sie deshalb unterschiedlich benutzt werden, aber technisch ist das der einzige Unterschied.
Mit Unions befasse ich mich später, sobald sie in meiner Lektüre erläutert werden.
Sind auch nicht so wichtig.
Bleibt nur noch die Frage, ob und wie ich ein struct samt unterklassen wiedergeben kann, quasi als Tabelle? (s.o.)
Die übliche Idee ist, dass eine Klasse eine Funktion hat, die alle ihre Member ausgibt. Wenn diese Klasse selbst Teil einer größeren Klasse ist, hat die größere Klasse auch solch eine Funktion, die dann die Ausgabefunktion der kleineren Klasse aufruft. Und so weiter. So bekommt man dann alles ausgegeben.
Üblicherweise nennt man die Funktion operator<<, aber das führt jetzt noch wahrscheinlich zu weit.
Butterbrot schrieb:
Enums sind doch immer Ints und werden damit auch gerne für den Enum-Hack verwendet, oder? So spart man sich z.B. ein #define MAX 42 für irgendwelche Arraygrößen und der Compiler kann aufgrund des Eintrages in der Symboltabelle, gleich einen Namen zum Fehler ausgeben und man muss nicht raten wo die 42 auf einmal herkommt.
Dafür gibt es in C++ const(expr).
-
xStrykex schrieb:
Okidoki, auch nochmal bissel rumgegoogelt wegen unterschied class und struct.
--> Ist verstandenSeppJ schrieb:
Sicher? Oft wird das nämlich falsch erklärt. Einziger Unterschied ist die Defaultsichtbarkeit (public/private). Eventuell kann man noch sagen, dass sie deshalb unterschiedlich benutzt werden, aber technisch ist das der einzige Unterschied.In diversen anderen Foren wurde es ebenso erklärt, dass der einzige Unterschied in der Sichtbarkeit wäre. (Zudem eine class einen höheren "Schutz" gewährt)
Zitat:
Bleibt nur noch die Frage, ob und wie ich ein struct samt unterklassen wiedergeben kann, quasi als Tabelle? (s.o.)
SeppJ schrieb:
Die übliche Idee ist, dass eine Klasse eine Funktion hat, die alle ihre Member ausgibt. Wenn diese Klasse selbst Teil einer größeren Klasse ist, hat die größere Klasse auch solch eine Funktion, die dann die Ausgabefunktion der kleineren Klasse aufruft. Und so weiter. So bekommt man dann alles ausgegeben.Üblicherweise nennt man die Funktion operator<<, aber das führt jetzt noch wahrscheinlich zu weit.
Hab ich das jetzt richtig verstanden, wenn ich sage, dass in der Klasse bzw der Struktur eine solche Funktion eingebaut werden muss?
-
xStrykex schrieb:
In diversen anderen Foren wurde es ebenso erklärt, dass der einzige Unterschied in der Sichtbarkeit wäre.
Gut.
(Zudem eine class einen höheren "Schutz" gewährt)
Häh?
Hab ich das jetzt richtig verstanden, wenn ich sage, dass in der Klasse bzw der Struktur eine solche Funktion eingebaut werden muss?
Ja. Von alleine passiert nix.
-
Zitat:
(Zudem eine class einen höheren "Schutz" gewährt)Häh?
*Höhere Schutzstrukturen, entschuldige
Gehe dabei davon aus, dass damit privat und public gemeint ist
-
Habe im Internet etwas gefunden, wie man eine Klasse/Struktur ausgeben könnte und habe es auf mein Beispiel angewendet. Ist für mich anscheinend noch viel zu schwer
Das hier ist bei rausgekommen:
#include<iostream> #include<string> using namespace std; int Anzahl = 0; struct Material { string Name; double Wert; int Gewicht; int Nummer; }; void M_Material(Material * m) { cout << "Folgende Materialen " << Anzahl << " sind in der Datenbank vorhanden:" << endl; for (int i; i<Anzahl; i++) { cout << "Material Nummer: " << m[i].Nummer << endl; cout << "Material Name: " << m[i].Name << endl; cout << "Material Gewicht: " << m[i].Gewicht << "kg" << endl; cout << "Material Wert: " << m[i].Wert << "Euro" << endl; } } int main() { Material Silber; Silber.Nummer = 1; Silber.Name = "Silber"; Silber.Wert = 1014.03; Silber.Gewicht = 1; Material Gold; Gold.Nummer = 1; Gold.Name = "Gold"; Gold.Wert = 43578.79; Gold.Gewicht = 1; cout << M_Material; cin.get(); return 0; }
Soweit verstehe ich die Zusammenhänge etc, ändert aber nichts an der Tatsache, dass das nicht funzzt. I-was scheint noch zu fehlen.
Würde sich jemand dazu bereit erklären, das mal richtig zusammenstellen? Aber bitte schlicht.Würde es gerne komplett verstehen, damit ich weiß, was beim nächsten mal gemacht und worauf geachtet werden muss.
Wenn das aber noch eine Nummer zu hoch für mich ist, sagt Bescheid, dann mach ich woanders weiter
Interessiert mich nur unheimlich
EDIT: Nach dem Beispiel von Kommentar #2 http://quake.ingame.de/forum/web-design-and-coding-343/c-problem-mit-struct-bzw-der-ein-ausgabe-funktion-251282/ @Mods: Wenn verlinken anderer Foren verboten ist o.ä., sagt bitte Bescheid
-
SeppJ schrieb:
Butterbrot schrieb:
Enums sind doch immer Ints und werden damit auch gerne für den Enum-Hack verwendet, oder? So spart man sich z.B. ein #define MAX 42 für irgendwelche Arraygrößen und der Compiler kann aufgrund des Eintrages in der Symboltabelle, gleich einen Namen zum Fehler ausgeben und man muss nicht raten wo die 42 auf einmal herkommt.
Dafür gibt es in C++ const(expr).
Wurde halt so in Effektive C++ Tipp 2 beschrieben.
-
Würde man wenig ändern wollen, könnte man das so anpassen;
int main() { Material alle_materialien[ 2 ]; Material Silber; Silber.Nummer = 1; Silber.Name = "Silber"; Silber.Wert = 1014.03; Silber.Gewicht = 1; alle_materialien[ Anzahl++ ] = Silber; Material Gold; Gold.Nummer = 1; Gold.Name = "Gold"; Gold.Wert = 43578.79; Gold.Gewicht = 1; alle_materialien[ Anzahl++ ] = Gold; M_Material( alle_materialien ); cin.get(); return 0; }
Schöner Stil ist das nicht, aber wird wohl klappen...
Die Ausgabe funktioniert auch besser, wenn i initialisiert wird:
for (int i = 0; i<Anzahl; i++)
Ciao
MM
-
xStrykex schrieb:
Soweit verstehe ich die Zusammenhänge [...]
Dann beschreib' bitte in eigenen Worten was deiner Meinung nach in deinem Beispiel passieren soll.
xStrykex schrieb:
[...] I-was scheint noch zu fehlen.
Kann man so nicht sagen. Das ist einfach unverstanden Zusammenkopiert.
xStrykex schrieb:
[...] Würde sich jemand dazu bereit erklären, das mal richtig zusammenstellen?
"Zusammenstellt"? Nein. Du musst programmieren lernen.
xStrykex schrieb:
[...] Aber bitte schlicht.
Würde es gerne komplett verstehen, damit ich weiß, was beim nächsten mal gemacht und worauf geachtet werden muss.
#include <vector> #include <string> #include <iostream> class Material { friend // bedeutet, folgende Funktion darf auch auf private Member von Material zutreifen. std::ostream& operator<<( std::ostream &os, Material const &material ); // jetzt gibt's für Material den << Operator. Links davon steht ein std::ostream (wie std::cout), rechts davon ein Material. private: static unsigned int id_counter; // statt deiner globalen int unsigned id; // negative ids sind witzlos, std::string name; double value; // (double evtl. unguenstig) int unsigned weight; // negatives gewicht auch. public: Material( std::string const &name, double const value, int unsigned const weight ) : id( ++id_counter ), name( name ), value( value ), weight( weight ) /* <- Initialisierungsliste */ {} // Material() ist der Konstruktor von Material. Er bekommt die // Werte übergeben, die das neue Material bekommen soll. }; unsigned int Material::id_counter = 0; // Implementierung des Operators: std::ostream& operator<<( std::ostream &os, Material const &material ) { // os steht links vom <<, material rechts. return os << "Material Nummer: " << material.id << "\nName: " << material.name << "\nGewicht: " << material.weight << " kg" << "\nWert: " << material.value << " Euro"; } int main() { std::vector< Material > materials; // ist ein haufen Material ;) materials.push_back( Material( "Silber", 1014.03, 1 ) ); // Ans Ende vom Haufen einen neues, mit dem Konstruktor materials.push_back( Material( "Gold", 43578.79, 1 ) ); // von Material erzeugtes Material anhängen. std::cout << "Folgende " << materials.size() << " Materialen sind in der Datenbank vorhanden:\n\n"; // Mit der Schleifenvariable i (ein Iterator) von begin bis end des vectors Materials laufen for( auto i = materials.begin(); i != materials.end(); ++i ) { std::cout << *i << "\n\n"; // und mit unserem operator<<() ausgeben. } }
xStrykex schrieb:
[b]Wenn das aber noch eine Nummer zu hoch für mich ist, sagt Bescheid, [...]
Wahrscheinlich. Oben steht, was du dir ansehen solltest.
-
Ok, vielen Dank erstmal an alle.
@Swordfish: Hast mir eindeutig mit dem letzten Post sehr viel weiter geholfen, zwar sind mir noch zwei/drei Sachen etwas unklar wie z.B. der Unterschied zwischen ostream und cout (in anderen Foren heißt es bloß, dass cout ein Member von ostream ist, in welchem Zusammenhang man aber welches benutzt, habe ich nicht herrausfinden können), aber für meine Verhältnisse super erklärt.Wie gesagt, vielen Dank
Swordfish schrieb:
xStrykex schrieb:
[...] I-was scheint noch zu fehlen.
Kann man so nicht sagen. Das ist einfach unverstanden Zusammenkopiert.
Habe erwähnt, dass ich mich an genanntem Bsp. orientiert habe, also bitte net ausschimpfen
Swordfish schrieb:
xStrykex schrieb:
[...] Würde sich jemand dazu bereit erklären, das mal richtig zusammenstellen?
"Zusammenstellt"? Nein. Du musst programmieren lernen.
Deswegen wälz ich jetzt mein Buch weiter
-
xStrykex schrieb:
SeppJ schrieb:
xStrykex schrieb:
(Zudem eine class einen höheren "Schutz" gewährt)
Häh?
[...] Gehe dabei davon aus, dass damit privat und public gemeint ist
. o O ( Befürchte schlimmes ... )
Was ist der Unterschied zwischen
foo_t
undbar_t
:struct foo_t { private: int value; public: foo_t( int const value ) : value( value ) {}; int get_value() const { return value; }; }; class bar_t { private: int value; public: bar_t( int const value ) : value( value ) {}; int get_value() const { return value; }; };
?
// edit: goddamnit.
-
Kein Unterschied
-
Ok, habe bisher nirgends gelesen, dass im struct auch privat & public zu verwenden sind, bzw verwendet werden können, immer nur im Zusammenhang mit class.
Dann weiß ich auch nicht, was damit gemeint ist und überhör das mal mit dem "Schutz".