Änderungen von Variablen in Variable speichern
-
wollte sehen ob man was in den Feldern abgeändert hat und wenn dann die Änderung in ner yesnochancel Messagebox anzeigen.
Is egentlich praktischer wenn ich erst ne Abfrage starte OB sich was geändert hat , falls dann die Messagebox anzuzeigen und auf den Inhalt einzugehen.
vista schrieb:
brauchst nicht die strings zu prüfen. edit-controls haben ein 'modified' flag.
--> CEdit::GetModify()nice to know : )
btw nich dass jmd das hier anschaut und falsch macht
es heißt |=short int wAenderungen = 0; if(Feld1.GetModify()) wAenderungn |= FELD1; if(Feld2.GetModify()) wAenderungn |= FELD2; ...
-
Has3 schrieb:
Da ich mich ja weiterbilden will
wollt ich wissen ob es da noch etwas eleganteres gibt.Ja, man kann da ein kleines Template bauen, welches jede Änderung registriert - etwa sowas
#include <iostream> #include <string> template< typename T > class Value { public: Value( const T& x ) : m_x( x ) , m_changed( false ) {} Value& operator=( const T& x ) { if( x != m_x ) { m_x = x; m_changed = true; } return *this; } bool hasChanged() const { return m_changed; } T get() const { return m_x; } void reset() { m_changed = false; } private: T m_x; bool m_changed; }; int main() { using namespace std; Value< string > feld1 = "Hallo"; feld1 = "Hallo"; if( !feld1.hasChanged() ) cout << "keine Änderung " << endl; feld1 = "Welt"; if( feld1.hasChanged() ) cout << "jetzt hat sich der Wert verändert " << endl; return 0; }Wenn notwendig, lässt sich Value<> natürlich aus so erweitern, dass sich der letzte Wert gemerkt wird. Der Zugriff auf den eigentlichen Wert geht mit get() (s.o.).
Gruß
Werner
-
Simon2 schrieb:
trotzdem ziehe ich meinen Einwand zurück: "Unschön" ist das nicht.
Wieso so zimperlich? '#define' für Konstanten ist grundsätzlich unschön.
-
Konrad Rudolph schrieb:
Simon2 schrieb:
trotzdem ziehe ich meinen Einwand zurück: "Unschön" ist das nicht.
Wieso so zimperlich? '#define' für Konstanten ist grundsätzlich unschön.
Weil ich meine Abneigung (die ich immer noch verspüre) in diesem Fall nicht konkret begründen kann. Ich hätte es anders gemacht ... aber nicht von Kollegen verlangt, es anders zu machen. Ursprünglich hatte ich diesen konkreten Fall für riskant empfunden ... jetzt bleibt nur die allgemeine Abneigung gegen #defines.
Gruß,
Simon2.
-
Werner Salomon schrieb:
Has3 schrieb:
Da ich mich ja weiterbilden will
wollt ich wissen ob es da noch etwas eleganteres gibt.Ja, man kann da ein kleines Template bauen, welches jede Änderung registriert - etwa sowas...
wie schon erwähnt: edit-controls kann man fragen, ob sich was verändert hat.
so elegant ein template sein mag (templates zu nutzen ist ja irgendwie immer elegant
), aber funktionalität nachzubauen, die schon existiert, ist niemals elegant.Simon2 schrieb:
Konrad Rudolph schrieb:
Simon2 schrieb:
trotzdem ziehe ich meinen Einwand zurück: "Unschön" ist das nicht.
Wieso so zimperlich? '#define' für Konstanten ist grundsätzlich unschön.
Weil ich meine Abneigung (die ich immer noch verspüre) in diesem Fall nicht konkret begründen kann.
kann es denn der Konrad begründen?

-
vista schrieb:
Simon2 schrieb:
Konrad Rudolph schrieb:
Simon2 schrieb:
trotzdem ziehe ich meinen Einwand zurück: "Unschön" ist das nicht.
Wieso so zimperlich? '#define' für Konstanten ist grundsätzlich unschön.
Weil ich meine Abneigung (die ich immer noch verspüre) in diesem Fall nicht konkret begründen kann.
kann es denn der Konrad begründen?

Ich denke, das kann er. Es gibt in C++ (im Gegensatz zu C) ein Sprachelement, welches das Definieren von Konstanten erlaubt. Damit gibt es keinen Grund mehr, auf den Präprozessor auszuweichen, welcher mehrere Nachteile hat:
- (a priori) keine Typensicherheit,
- zerstört die Logik des Programms und erschwert das Debuggen,
- stellt prinzipiell keinen konstanten Wert dar (s. Beispiel 1),
- ist fehleranfällig (z.B. durch vergessene Klammern, Beispiel 2),
- last, but not least: Zerstört Namensbereich-Zuordnungen und ist somit destruktiv.// So macht man es in C++: namespace math { const double pi = std::atan(1.0) * 4.0; } // So macht man es nicht. // Beispiel 1, wird jedes Mail neu berechnet, wenn der Code benutzt wird: #define pi (std::atan(1.0) * 4.0) cout << pi << endl; // Wert wird berechnet cout << pi << endl; // Wert wird erneut berechnet. // Beispiel 2, hier ham' wir den Salat. #define drei 2 + 1 cout << drei * 4 << endl;
-
Konrad Rudolph schrieb:
#define pi (std::atan(1.0) * 4.0) #define drei 2 + 1du hast es absichtlich falsch gemacht. damit kannst du niemanden überzeugen.
#define pi 3.1415926536 #define drei (2 + 1)nun sind die fehler weg.

-
gut zu wissen

werd mir mal das template anschaun wenn ich zeit hab.vielen Dank für die Hilfe
-
// irgendwo in den Weiten der Headers der vielen Libraries... // x1.h void drei(); enum { pi };// eigene header // A1.h #define pi 3.1415926536 #define drei (2 + 1)#include <eine_header_die_irgend_eine_header_X1_includiert.h> #include "A1.h" void foo() { int i = drei * pi; }Viel Spass bei der Fehlersuche!!!!!

-
vista schrieb:
du hast es absichtlich falsch gemacht. damit kannst du niemanden überzeugen.
Bei der Verwendung von PI ist mir eine exakt berechnete Version auf jeden Fall lieber als ein fest vorgegebener Wert (klar, für die meisten Anwendungen reicht sogar 3.14, aber sag das mal einem Puristen :D). Und ansonsten zeigen die Beispiele recht deutlich die Probleme des Präprozessors - #define ist eine dumpfe Textersetzung und wenn dabei Fehler auftreten, kannst du die nur schwer lokalisieren.
In C war #define womöglich noch verwendbar, aber in C++ ist es in den meisten Fällen unnötig (da gibt es Möglichkeiten mit vergleichbarer Anwendbarkeit, aber ohne die Schwächen des Präprozessors).
-
vista schrieb:
Konrad Rudolph schrieb:
#define pi (std::atan(1.0) * 4.0) #define drei 2 + 1du hast es absichtlich falsch gemacht.
Natürlich. Ich sagte ja auch, es sei fehleranfällig. Was glaubst Du, wie häufig diese Klammern vergessen werden!
damit kannst du niemanden überzeugen.
Jedem das seine. Aber in großen Teamprojekten ist man über jede eliminierte potentielle Fehlerquelle froh.
Natürlich kann man auch mit #defines's fehlerfreien Code schreiben, das habe ich nicht bestritten. Aber es ist definitiv schwerer, als wenn man es sein lässt.
#define pi 3.1415926536Ich bevorzuge die Definition über den Arkustangens.
-
ok, dass #define grundsätzlich fehlerträchtiger ist als etwas anderes kann ich nicht nachvollziehen, denn meistens handelt man sich fehlerquellen durch falsche anwendung ein und das kann auch mit anderen konstrukten passieren.
..und dass #define immer eine stumpfe textersetzung macht ist auch nicht ganz richtig. etwas rechnen kann es ja auch.
aber da ich von C++ null plan habe (ich programmiere meistens C), schenke ich euch mein blindes vertrauen und glaube euch, dass es in C++ andere möglichkeiten gibt, die besser ins konzept der sprache passen und die man als C++ progger deshalb #define vorziehen sollte.

-
vista schrieb:
..und dass #define immer eine stumpfe textersetzung macht ist auch nicht ganz richtig. etwas rechnen kann es ja auch.
Echt? Das beste, was der Präprozessor "rechnen" kann, sind die Operatoren # und ##. Bei einem
#define drei (1+2)wird jedes Vorkommen von 'drei' textuell ersetzt, ohne daß der Präprozessor sind den Inhalt der Ersetzung ansieht - der Rest ist dann Sache des Compilers (der die Berechnung von (1+2) rausoptimieren kann).
-
CStoll schrieb:
vista schrieb:
..und dass #define immer eine stumpfe textersetzung macht ist auch nicht ganz richtig. etwas rechnen kann es ja auch.
Echt? Das beste, was der Präprozessor "rechnen" kann, sind die Operatoren # und ##. Bei einem
#define drei (1+2)wird jedes Vorkommen von 'drei' textuell ersetzt, ohne daß der Präprozessor sind den Inhalt der Ersetzung ansieht - der Rest ist dann Sache des Compilers (der die Berechnung von (1+2) rausoptimieren kann).ich kann mich jetzt täuschen, aber als ich mir mal c-code nach dem preprocessor-durchlauf angeschaut habe (war' s jetzt beim codewarrior?)
da wurde so etwas:#define drei (1+2) ... int x = drei;das:
int x = 3;mag aber sein, das in der regel die präprozessoren nicht so schlau sind...

-
Der Compiler macht eine 3 draus, wenn er das sieht. Aber nicht der Präprozessor. Und ja, du hast von C++ keinen Plan, sonst würdest du das nicht so in deinem jugendlichen Leichtsinn sagen, das Makros nicht so übel sind. Denn du mußt dir einem bewusst werden:
static const int hallo = 2;Das Ding verbraucht KEINEN Speicher. (außer der Compiler ist so dämlich, aber dann würde ich den nicht weiter benutzen) Ich habe also nicht nur wie Makros keinen Speicherverbrauch, sondern auch noch ein Sprach-Element in Gebraucht. Ich kann das Hallo sogar in einen Namespace legen. Das geht alles nicht mit Makros. Es gibt KEINEN Grund dafür, wenn man C++ programmiert.
-
Artchi schrieb:
static const int hallo = 2;Das Ding verbraucht KEINEN Speicher.
demnach müsste ein 'sizeof(hallo)' 0 ergeben.
ist es so?
wäre jedenfalls unlogisch wenn nicht...

-
Stimmt. *mir selbst in den arsch tritt*
-
Sizeof von hallo ergibt natürlich die Größe von int, und nicht 0. Wenn man die Adresse von hallo im Programm nimmt muss man auch (bei statischen Membern) Speicher für die Konstante zur Verfügung stellen, und dessen Größe ist logischerweise auch 4. Man könnte sogar mit const_cast-Gemeinheiten den Wert an dieser Stelle ändern.
Aber darum gehts garnicht, das wichtige ist doch dass solche Konstanten in C++ (im Gegensatz zu C) vom Compiler als konstant angesehen und damit zur Compile-Zeit ersetzt werden können. Selbst wenn Du den Wert per const_cast zur Laufzeit änderst ist der Compiler berechtigt davon auszugehen dass Du das nicht tust.
-
Es ist halt ein Sprach-Element und kein Textersetzer-Element. Man man sollte immer Sprachelemente bevorzugen. Da der Compiler die Hoheit über den endgültigen Code hat.
-
LordJaxom schrieb:
Sizeof von hallo ergibt natürlich die Größe von int, und nicht 0. Wenn man die Adresse von hallo im Programm nimmt muss man auch (bei statischen Membern) Speicher für die Konstante zur Verfügung stellen, und dessen Größe ist logischerweise auch 4. Man könnte sogar mit const_cast-Gemeinheiten den Wert an dieser Stelle ändern.
hmmm?

jetzt bin ich ganz schön verwirrt. konstanten, deren wert man zur laufzeit ändern kann? wie passt denn das zusammen
so langsam komme ich zu dem schluss, dass #define hierfür doch besser geeignet ist.