.
|
|
| Autor | Beitrag |
|---|---|
|
000 21.08.2001, 15:56 Hanky |
moin, eine kleine Frage.. also z.B. bei einer if Abfrage.. -- |
|
Profil || Suche |
|
001 21.08.2001, 16:04 Hellfire |
Vor dem Compilen werden alle Codestellen, wo BLABLA und BLAANDBLUB steht durch 13 ersetzt. Also bei ner if Abfrage ist es relativ egal, was du abfragst, da beide Makros für den selben Wert stehen. --Dieser Beitrag wurde am 21.08.2001 um 16:04 von Hellfire bearbeitet. |
|
Profil || Suche |
|
002 21.08.2001, 18:11 apfelkorn |
der Hauptgrund, warum man #define's verwendet ist, dass es übersichtlicher wirkt für den Programmierer... Im Endeffekt könntest du z.b. statt: #define BLUBBER 1 if (flags==BLUBBER) auch: if (flags==1) schreiben. Das untere ist zwar kürzer, aber was ist übersichtlicher? Weißt du z.b. nach 1 std. programmieren noch, ob BLUBBER 1 oder 2 ist? Der Compiler weiß es, und setzt daher auch alle #defines ein. Also würde für den Compiler der zu Compilierende Code vom ersten Beispiel für den Compiler wie das untere aussehen. --Dieser Beitrag wurde am 21.08.2001 um 18:13 von apfelkorn bearbeitet. |
|
Profil || Suche |
|
003 21.08.2001, 18:21 Gollum |
Zum Festlegen von konstanten Zahlenwerten sollte man aber const verwenden (vorrausgesetzt du kompilierst mit einem c++ kompiler)... also statt #define's unter c++ nur für makros --[url="http://www.thelordoftherings.com/cgi-bin/get-image.pl?ID=alan-lee-058 "]-N/A-[/url]
|
|
Profil || Suche |
|
004 21.08.2001, 19:52 Prefect |
const ist aber dumm.. da riskierst du nämlich, dass der Compiler/Linker unnötig Speicher für die ganzen consts reservieren. cu, Widelands - Gemütliche Aufbaustrategie, Free Software |
|
Profil || Suche |
|
005 21.08.2001, 19:59 TheTinySteini |
Vor allem muss man ja bei const auch noch angeben, was für ein Typ das sein soll. Hm, das weiß ich aber oft in dem Moment auch noch gar nicht =) TheTinySteini |
|
Profil || Suche |
|
006 21.08.2001, 20:57 Mazze |
Was sagt ihr zu enum? --BattleTech-MOD: |
|
Profil || Suche |
|
007 21.08.2001, 21:31 Gollum |
Well. klar schaut define 10000x besser aus :) is halt irgendwie klassisch so :) Dennoch _sollte_ man in C++ mit const arbeiten. Speicher wird für const werte sicher nicht reserviert, wäre ja auch irgendwo sinnlos :) Daß man den Typ festlegen muss ist natürlich auch eher positiv, so kann man zB zwischen int und float differenzieren, und dann auch an mit int und float überladene funktionen den auf jeden fall richtigen datenyp weitergeben. aber ganz ehrlich gesagt verwende ich selbst meist #define :) [/EDIT] --[url="http://www.thelordoftherings.com/cgi-bin/get-image.pl?ID=alan-lee-058 "]-N/A-[/url]
Dieser Beitrag wurde am 21.08.2001 um 21:43 von Gollum bearbeitet. |
|
Profil || Suche |
|
008 21.08.2001, 22:11 TheTinySteini |
enum rulez, es muss halt richtig eingesetzt werden. Gerade bei Optionen kann einem enum viel Tipparbeit ersparen. Überladene Funktionen: naja, is ein Argument, aber dann kann ich zur Not auch noch #define EINEZAHL 10.0 schreiben, oder gar #define EINEZAHL 10.0f, beides wird zur Folge haben, dass er die float-Version nimmt. Obwohl, bei der ersten Variante bin ich mir da nicht ganz sicher. --TheTinySteini |
|
Profil || Suche |
|
009 22.08.2001, 18:59 Kriz |
Gollum hat Recht! Man sollte #define nur für Abschnittspräkompilierung verwenden und NICHT für die Definition von Konstanten!!! Die Ausnahme bilden da metaportable Codesegmente, die auf Systemen laufen sollen, die zum Bleistift mit bool, false und true sowie NULL nichts anfangen können. Auf diesen Systemen wäre es angebracht, Code in der Art
usw. zu implementieren. Späße wie
sind Anfängerkacke und zeugen von sehr schlechtem Programmierstil (und Programmierkenntnissen). Also Konstanten immer so initialisieren:
Stellen sich jetzt nur noch zwei Fragen: Erstens "Wieso?" und zweitens "Was sind Abschnittspräkompilierungen?". Zu erstens: Richtige Konstanten auf Basis von C++ werden typgeprüft, was #defines definitiv nicht machen (Das gilt übrigens auch für solche Unarten wie Funktionsmakros, von denen zwar abgeraten wird, aber es trotzdem jeder macht =). Zu zweitens: Die Aufteilung von Klassen in Klassenheader und Klassenquellcode wird am Besten in C++ mit #define geregelt. Da es durchaus vorkommt, daß der Präprozessor viele Headers und Quellcodes während des Kompilierens mehrfach einbinden muß aufgrund der Gesamtstruktur des Quellcodes, kann es je nach Compiler und Code zu Fehlern kommen. Das umgeht man mit der Abschnittspräkompilierung:
Der Sinn ist klar: Sobald die Headerdatei AAA.h einmal vom Präprozessor eingebunden worden ist, hat er auch das Makro AAA_H definiert. Sollte im späteren Preprocessing die Header AAA.h nochmals eingebunden werden, so erkennt der Präprozessor, daß das Makro AAA_H existiert und ignoriert allen Code bis zum dazugehörigen #endif. Das war schon die ganze Kunst. Also, Konstanten immer mit const deklarieren usw. und Makros nur für solche Arbeiten wie oben beschrieben benutzen. Jaja, ich weiß, die meisten sind faule Säcke und würden mit #define am Liebsten ganze Programme definieren =) Aber so schreibt es das Software Engineering für C++ eben vor und wer gute Arbeit leistet, der wird auch entsprechend belohnt mit wenig Wartung und Debugging... Cu --K:R-I)Z++ |
|
Profil || Suche |
|
010 23.08.2001, 22:07 Hanky |
da fragt man nur eine Frage..:D DANKE LADYS! (das hat eine tiefe männliche Stimme sanft und beruhigend gesatg.. es ist meine Stimmme!) -- |
|
Profil || Suche |
|
011 24.08.2001, 18:15 TheTinySteini |
Stimmt, das ist "Anfängerkacke und [zeugt] von sehr schlechtem Programmierstil (und Programmierkenntnissen)", denn das "=" muss weg :P Naja, und sonst: Es ist wirklich nur die Typüberprüfung, die für const spricht. Nix weiter. Und ehrlich gesagt, manchmal suckt Typüberprüfung einfach gewaltig, da hab ich lieber die Flexibilität einer #define-Konstante. Und wenn man den Dingern nen vernünftigen Namen gibt, dann sind Verwechslungen eigentlich sowieso ausgeschlossen. Ich meine, dass man nicht sowas hier machen sollte: TheTinySteini |
|
Profil || Suche |
|
012 24.08.2001, 18:21 Prefect |
Ach Kriz, du unverbesserlicher C++-Moralapostel ;) #define ist am stylischsten, enum bringt Sinn für so Auswahloptionen. const... naja, im Kontext von const char *GetText() const; schon, aber sonst? Nein danke. Ach ja, und const-Variablen können durchaus Speicher belegen, nämlich dann, wenn man irgendwo einen Pointer darauf verwendet. TTT: Hungarische Notation ist wirklich was feines. Und was die meisten immer vergessen: Dosis fazit venenum. Ach ja, Exceptions sind wirklich was, von dem man die Finger lassen sollte. Schaut euch das Zeug nur mal im Debugger an :| cu, Widelands - Gemütliche Aufbaustrategie, Free Software Dieser Beitrag wurde am 24.08.2001 um 18:25 von Prefect bearbeitet. |
|
Profil || Suche |
|
013 24.08.2001, 19:02 Andy_ |
Tztztz, Prefi 42 Es gibt keinen Sinn des Lebens. Dieser Beitrag wurde am 24.08.2001 um 19:02 von Andy bearbeitet. |
|
Profil || Suche |
|
014 24.08.2001, 19:41 Mazze |
Hangarisch? BattleTech-MOD: |
|
Profil || Suche |
|
015 26.08.2001, 17:34 Kriz |
@TTT: Jo, das = muß weg :) @Prefi:
Soviel ich weiß, regelt das abschließende const bereits die Tatsache, daß der Rückgabewert konstant ist. Kann aber sein, daß das vordere const noch ein Relikt aus der C-Zeit ist :-? Hehehe, da fällt mir wieder ein, wie ich einem Spack versucht hab zu erklären, warum Get-Methoden soweit wie möglich als const deklariert werden sollten (in Bezug auf Kopierkonstruktoren). Der Sack hat das doch net begriffen, was ich von ihm wollte... Der hatte brav weiter seinen Kopierkonstruktor nach der Methode
gebastelt und sich gewundert, wieso in Bruchteilen von Sekunden der verfügbare Hauptspeicher übergelaufen war (muhahaha)... --K:R-I)Z++ |
|
Profil || Suche |
|
016 28.08.2001, 20:17 Prefect |
Das mit dem Hauptspeicheüberlauf dürfte aber nicht am const, sondern am Pass by Value (statt Pass by Reference) liegen... --- ist die Deklaration einer Methode in einer Klasse. Das erste const besagt, dass der Aufrufer den Datenbereich, auf den der zurückgegebene Pointer zeigt, nicht verändern darf. char *Foo::DupText() const cu, Widelands - Gemütliche Aufbaustrategie, Free Software |
|
Profil || Suche |
|
017 29.08.2001, 01:12 Kriz |
Das zweite const besagte eigentlich, daß wenn das Objekt konstant ist, daß auch nur dann solche Methoden aufgerufen werden dürfen, die als const deklariert worden sind. Ansonsten hat man auf diese Funktionen keinen Zugriff von außen, selbst wenn sie public sind! Das erste const ist so wie Prefi es gesagt hat =) *** Für den Rest der gottlosen Nicht-C++er *** In Bezug auf den Kopierkonstruktor ist eine konstante Methode lebenswichtig, denn man übergibt ein Referenz der eigenen Klasse stets konstant an den Kopierkonstruktor der eigenen Klassen, sonst knallt es (wie weiter oben gesagt) sofort den verfügbaren Hauptspeicher zu:
Ohne Referenz ruft sich der Standardkonstruktor von CFoo auf, denn das simple bar ist eine neue Instanz von CFoo. Bei der Übergabe der Kopierwerte erzeugt CFoo dann (infolge seines eigenen Kopierkonstruktors) wiederum eine neue Instanz von CFoo, diese wiederum und diese wiederum usw. Es ensteht eine Rekursion, die den RAM vollknallt. Also verwendet man eine Referenz auf die eigene Klasse (einen impliziten Zeiger also). Dummerweise kann man aber so die Inhalte des Arguments (der zu kopierenden Klassenreferenz nämlich), verändern und das ist böse böse... Also macht man eine konstante Referenz (konstantes Objekt). Dieses konstante Objekt aber nur über konstante Methoden aufgerufen werden. Nichtkonstante Methoden erzeugen beim Aufrufen Fehlermeldungen. Daher erhält eine konstante Methode am Ende das const. Man kann aber auch Elementwerte in konstanten Objekten ändern. Dazu muß dem änderbaren Element das Schlüsselwort mutable vorangestellt werden und die konstante Methode muß natürlich dieses Element bearbeiten (sonst ist das ja witzlos). Desweiteren kann man die Konstantheit eines konstanten Objekts im Nachhinein weg-casten und so übergehen. Beispiel:
Cu --K:R-I)Z++ Dieser Beitrag wurde am 29.08.2001 um 01:12 von Kriz bearbeitet. |
|
Profil || Suche |
|
018 29.08.2001, 12:12 Mazze |
i? BattleTech-MOD: |
|
Profil || Suche |
|
019 29.08.2001, 20:43 Prefect |
Kriz, ein Copyconstructor müßte eigentlich durchaus auch einen nicht-const-Parameter nehmen können, genauso wie ein operator=. Wir wär's mit einem =-Operator der von links nach rechts statt von rechts nach links kopiert? *g* Und ich sage immer noch, dass das zweite const ein Typmodifizierer für den this-Pointer ist. Dass man bei einem const-Objekt keine nicht-const-Methode aufrufen kann ist natürlich klar, da dadurch der this-pointer von (const CFoo *) auf (CFoo *) gecastet werden müßte. Bzw:
Es kann übrigens gut sein, dass wir das gleiche meinen, es aber anders formulieren... cu, Widelands - Gemütliche Aufbaustrategie, Free Software Dieser Beitrag wurde am 29.08.2001 um 20:44 von Prefect bearbeitet. |
|
Profil || Suche |
|
020 29.08.2001, 22:39 Kriz |
Natürlich kann der Kopierkonstruktor ne nichtkonstante Referenz annehmen, aber dann kann man (wenn die Klasse öffentlich als Bibliothek oder so bereitgestellt wird) in seiner eigenen Implementierung im Kopierkonstruktor das Parameterobjekt verändern, was ja nicht Sinn der Sache ist (aber das muß ich dir ja nicht weiter erklären). Desweiteren reden wir tatsächlich von ein- und demselben, nur daß du es in komplizierte Worte packst =). Auch wenn ich mir nicht da so 100%ig sicher bin in deiner Aussage, da der this-Zeiger eines konstanten Objekts durch seine Deklaration usw. mittels voranstehendem const in diese Richtung modifiziert wird. Also habe ich mal in meinen alten Akten und Büchern nachgeblättert. Und in der Tat ist es wohl eher so, wie es meine, daß das 2. const eine Art Modifizierer ist, der als Fahrschein für konstante Methodenaufrufe dient. Im Prinzip genauso ein Bezeichner wie für abstrakte Methoden: Ist ja auch schnurz, jedenfalls brauchts konstante Methoden, die von konstanten Objekten aufgerufen werden... Cu PS: Da fällt mir ein: Wieso hat es nie ein Schlüsselwort abstract gegeben in C++? Ist logischer zu schreiben K:R-I)Z++ Dieser Beitrag wurde am 29.08.2001 um 22:41 von Kriz bearbeitet. |
|
Profil || Suche |
|
021 30.08.2001, 17:08 Hanky |
Das frag mal die von Borland oder MS...:P -- |
|
Profil || Suche |
|
022 30.08.2001, 17:27 Kriz |
Nope, das wäre eine Frage an Bjarne Stroustrup gewesen... --K:R-I)Z++ |
|
Profil || Suche |
|
023 30.08.2001, 17:38 Hanky |
hat der alles alleine gemacht? (c/C++) -- |
|
Profil || Suche |
|
024 30.08.2001, 17:42 Kriz |
In meinem C++-Online-Tut auf CAWS steht ganz genau, wer was wann wie wo gemacht hat =) --K:R-I)Z++ |
|
Profil || Suche |
|

