'dynamische' konstanten in klassen
-
hi!
gibt es eine moeglichkeit eine variable in einer klasse so zu gestalten, dass sie mit einem standartwert initialisiert wird (z.b. 0) und sich dann zu laufzeit genau einmal veraendern kann? also, dass sie dann von einer membermethode veraendert werden kann und danach als konstant gekennzeichnet wird oder so?
danke schoen,
hwm
-
Hi du,
schau dir mal zu deiner Frage mit dem initialisieren den Konstruktor an, der kann dir da weiterhelfen.
Willst du deine Variable in der Klasse private deklarieren, oder verstehe ich dich da falsch?Gruß Kitty
-
du der konstanten membervariable ja mal den const-qualifier klauen:
void klasse::funktion_die_member_veraendert() /*leider nicht const*/ { const_cast<int&>(m_const)=5; }
-
einen versuch wert schrieb:
du der konstanten membervariable ja mal den const-qualifier klauen:
void klasse::funktion_die_member_veraendert() /*leider nicht const*/ { const_cast<int&>(m_const)=5; }
Damit lässt sich die Variable aber nicht nur einmal verändern sondern beliebig oft.
Mein Ansatz ist:
- die Variable ganz normal anlegen
- zusätzlich ein flag mitführen, wo gespeichert wird, ob die Variable schon
geänder wurde oder nicht. wenn geändert, keine Änderung durchführen.
-
proga schrieb:
Mein Ansatz ist:
- die Variable ganz normal anlegen
- zusätzlich ein flag mitführen, wo gespeichert wird, ob die Variable schon
geänder wurde oder nicht. wenn geändert, keine Änderung durchführen.irgendwie ist der asatz häßlich. du führst zusätzlich eine boolsche variable mit, hast irgendwo ein paar doofe if-abfragen, die jedesmal ausgeführt werden müssen um zu gucken ob geschrieben werden darf.
-
Ich finde generell die Anforderung an die Variable seltsam. Normalerweise wird eine Konstante einmalig initialisiert und das wars dann. Nicht-Konstanten können halt jederzeit verändert werden. Und wenn man will, dass die Variable nur einmal geändert wird, dann sollte man auch die Memberfunktion auch nur einmal aufrufen.
@kruemel0809
Darf man mal fragne wofür das sein soll?
-
einen versuch wert schrieb:
proga schrieb:
Mein Ansatz ist:
- die Variable ganz normal anlegen
- zusätzlich ein flag mitführen, wo gespeichert wird, ob die Variable schon
geänder wurde oder nicht. wenn geändert, keine Änderung durchführen.irgendwie ist der asatz häßlich. du führst zusätzlich eine boolsche variable mit, hast irgendwo ein paar doofe if-abfragen, die jedesmal ausgeführt werden müssen um zu gucken ob geschrieben werden darf.
Ich habe nicht gesagt dass mein Ansatz schön ist. Es ist aber die Anforderung erfüllt, eine Variable zur Laufzeit nur einmal ändern zu können. Dein Ansatz im Gegensatz, erfüllt die Anforderung nicht, denn man könnte die Varibale durch wegkasten des const beliebig oft ändern. Dann kann man const auch direkt weglassen
-
einen versuch wert schrieb:
irgendwie ist der asatz häßlich. du führst zusätzlich eine boolsche variable mit, hast irgendwo ein paar doofe if-abfragen, die jedesmal ausgeführt werden müssen um zu gucken ob geschrieben werden darf.
Na und? Die Abfragen kann man alle schön in einem generischen Objekt verstecken. Hast Du eine bessere Idee, wie man Zugriffsrechte steuern soll?
#include <iostream> #include <stdexcept> using namespace std; template<class T> class ModifyOnlyOnce { public: ModifyOnlyOnce(const T& init = T()) : value(init), modified(false) {} ModifyOnlyOnce(const ModifyOnlyOnce<T>& rhs) : value(rhs.value), modified(false) {} // Bem.: operator= kann in diesem speziellen fall gleich const zurückliefern, // da weitere Änderungen sowieso nicht zulässig sind template<class U> const ModifyOnlyOnce<T>& operator=(const U& rhs) { if(modified) throw ::std::logic_error("this object must not be modified twice"); value = rhs; modified = true; return *this; } operator const T&() const { return value; } private: T value; bool modified; }; int main() { try { ModifyOnlyOnce<int> i; cout << i << endl; i = 5; cout << i << endl; i = 10; cout << i << endl; } catch(const exception& e) { cerr << "Error: " << e.what() << endl; } }
-
hola
hab folgenden source mal gefunden, is zwar urhaesslich, funkt aber. zumindest beim bcb:
// h-file class ChangeConst { private: int a; char t; const int b; int c; public: ChangeConst(void); ~ChangeConst(void); void change_once(int zahl); int GetB(void) { return b; } }; // cpp-file ChangeConst::ChangeConst(void) : a(0), b(0), c(0) { // do something } ChangeConst::~ChangeConst(void) { // do something } void ChangeConst::change_once(int zahl) { if(!b) { const int *p = &b; int this_address = (int)this; int b_address = (int)p; int offset = b_address - this_address; if(offset & 0x3) this_address += offset & 0x3; int *q = (int*)this_address; *(q + (offset >> 2)) = zahl; } }
Meep Meep
-
Meep Meep schrieb:
hola
hab folgenden source mal gefunden, is zwar urhaesslich, funkt aber. zumindest beim bcb:
// h-file class ChangeConst { private: int a; char t; const int b; int c; public: ChangeConst(void); ~ChangeConst(void); void change_once(int zahl); int GetB(void) { return b; } }; // cpp-file ChangeConst::ChangeConst(void) : a(0), b(0), c(0) { // do something } ChangeConst::~ChangeConst(void) { // do something } void ChangeConst::change_once(int zahl) { if(!b) { const int *p = &b; int this_address = (int)this; int b_address = (int)p; int offset = b_address - this_address; if(offset & 0x3) this_address += offset & 0x3; int *q = (int*)this_address; *(q + (offset >> 2)) = zahl; } }
Meep Meep
dann kannst du genausogut const_cast verwenden, dass ist portabel, effizienter und man sieht wenigstens, was passiert.
template < class T > class ChangeOnce { public: ChangeOnce(T const& initialValue = T() ) : v( initialValue ), changed( false ) { } ChangeOnce(ChangeOnce<T> const& rhs) : v( rhs.v ), changed( false ) { } ChangeOnce<T> const& operator=(ChangeOnce<T> const& rhs) { return *this = rhs.v; } ChangeOnce<T> const& operator=(T const& rhs) // kann nur einmal ändern, daher reference to const als returntyp { if( changed ) throw std::exception(); v = rhs; changed = true; return *this; } operator T() const { return v; } private: T v; bool changed; };