Stack & const
-
Hallo Leute,
ich möchte eine Stackimplementation aus Nicolai Josuttis "objektorientiertes Programmieren in C++" verwenden, um Events in einem Stack zu speichern (EventQueue). Die Events werden dabei durch Enumeration festgelegt – etwa in dieser Form:
enum Glob_Events {Event1 = 0, Event2, Event3}; enum StateMachiens {SM1 = 0, SM2, SM3};
Bei Auftreten des Events, soll in einer struct der Event und dessen Destination abgespeichert werden:
struct Events { unsigned const TheEvent; unsigned const TheMachine; //int EventAge; Events(unsigned const TheEvent, const unsigned TheMachine) : TheEvent(TheEvent), TheMachine(TheMachine) {}; Events() : TheEvent(0), TheMachine(0) {}; };
Natürlich dürfen und sollen sich die Events nach deren Entstehung nicht verändern, weswegen ich mich entschied, diese in der struct als const zu initialisieren. Wenn man diese struct in dem Stack mit einer push- artigen Aktion abspeichern will, stößt man allerdings wegen der const auf ein Problem:
//push template <class T> void Stack<T>::push (T& x) { //increase memory if required if(size <= numElems) { T* tmp = elems; size *= 2; elems = new T[size]; //copy eexciting elemnts into memory for (int i=0; i<numElems; i++) { elems[i] = tmp[i]; //const objects cannot be coppied… } delete [] tmp; //delete all! tmp's } elems[numElems++] = x; }
Nun könnte man die Events auch einfach nur als "unsigned" in der (nicht const) struct abspeichern – aber kann ich mir sicher sein, dass der Event sich nicht verändert wird ?
-
Hi, müssen Konstanten nicht einen festen Wert haben, der sich nicht verändern lässt? Und muss nicht auch der Datentyp angegeben werden?
LG
-
Hallo,
ich habe jetzt einfach mal einen "=" eingebaut, womit es scheinbar geht - aber ist das sinnvoll ?
struct Events { unsigned const TheEvent; unsigned const TheMachine; //int EventAge; Events(unsigned const TheEvent, const unsigned TheMachine) : TheEvent(TheEvent), TheMachine(TheMachine) {}; Events() : TheEvent(0), TheMachine(0) {}; const Events &operator=(const Events *obj) { //edited: &obj -> *obj return *this; } };
müssen Konstanten nicht einen festen Wert haben, der sich nicht verändern lässt? Und muss nicht auch der Datentyp angegeben werden?
-> Ja, Konstanten sollen einen festen Wert haben
-> Ich habe irgendwo mal gelesen, dass enum- typen vom Type "unsigned const" sind - keine Ahnung ob das stimmt.
-
Nein nein, rein syntaktisch ist das schon richtig, was Op da schreibt.
Aber konzeptionell ist das suboptimal.
Erstmal, wieso schreibst du einen Stack-Datenstruktur selbst? Wieso nutzt du nicht std::stack?In beiden Fällen müssen die Daten nämlich kopiert werden (oder wenigstens gemovet). Was std::stack da erfordert müsste ich nachschauen.
Aber du kannst deine Events hinter einer Klasse wegkapseln und einfach keinen schreibenden Zugriff darauf geben, so dass sich die Events nicht ändern können von außen. Wenn die Interna deiner Klasse die ändern, dann hast du da die volle Kontrolle drüber und solltest das halt nicht machen, wenn dus nicht brauchst.
Es ist oft eh keine gute Idee Datenmember von Klassen konstant zu machen, weil du damit die Kopierbarkeit angreifst:
Foo a = ...; Foo c(a); // geht zu kopieren Foo b = a; // derselbe Konstruktor wie oben Foo a = Foo(...); // geht nicht mehr
Über Klasseninterna hast du (allein) die volle Kontrolle, und viel öfters möchtest du dann Daten nicht ändern (indem du sie einfach nicht von aussen zugreifbar machst) oder der User macht dein ganzes Objekt direkt konstant.
-
Achja, und ich würde dir empfehlen enum classes zu verwenden. Und statt der unsigned Konstante eine Instanz von deinem enum...
-
Scheinbar funktioniert dies doch nicht so wie gedacht - und zwar liefert
//push template <class T> void Stack<T>::push (T& x) { //increase memory if required if(size <= numElems) { T* tmp = elems; size *= 2; elems = new T[size]; //copy eexciting elemnts into memory for (int i=0; i<numElems; i++) { printf("Copying \n"); elems[i] = tmp[i]; } delete [] tmp; //delete all! tmp's } //Argument printf("%d %d \n", ((Events) x).TheEvent, ((Events) x).TheMachine ); //geht T* test = new T; test = &x; printf("%d %d \n", ((Events) *test).TheEvent, ((Events) *test).TheMachine ); //geht nicht numElems++; elems[numElems] = x; printf("%d %d \n", ((Events) elems[numElems]).TheEvent, ((Events) elems[numElems]).TheMachine ); }
..die Operation "elems[numElems] = x;" nur die default- Initialisiation der
Events- struct, nämlich "0,0". Vermutlich liegt es am "=" operator in der struct - dieser funktioniert natürlich nur bei der Initialisierung etwa so:Events test = newEvent2; //geht
test = newEvent2; /geht nicht(Aber das wollte mir sicher der Vorposter auch mit seinem Post sagen.)
Da werde ich wohl auf const verzichten müssen...