Hallo!
Gibt es irgendwo ein Tutorial wo die grundlegenden Unterschiede zwischen
der normalen c++ programmierung und der Implementierung am AVR dargelegt
sind?
Jetzt im speziellen beim Konstruktor: Habe schon zwei schreibweisen
gesehen, die mir nicht ganz klar sind.
ClassA hat einen Konstruktur welcher einen u8 entgegen nimmt
1
ClassAa=ClassA(2);oder
2
ClassAa(2);
Was ist der Unterschied bei diesen Anweisungen?
Die Anlegung einer Variable (a) dient nur um auf die statischen Elemente
zuzugreifen oder?
lg
Christian J. schrieb:> Was ist der Unterschied bei diesen Anweisungen?
Die Schreibweise.
> Die Anlegung einer Variable (a) dient nur um auf die statischen Elemente> zuzugreifen oder?
Nein.
a ist eine Instanz der Klasse.
Das alles hat mit AVR oder nicht AVR nichts zu tun.
Danke erstmal...
Also ist zwischen den zwei Schreibweisen kein Unterschied?
Wie werden diese Objekte am µC verwaltet?
Wenn ich jetzt zwei Instanzen erzeuge und jede Instanz ihre eigenen
Eigenschaften hat, wo werden wiese abgelegt?
Wenn ich jetzt eine Methode der beiden Instanzen aufrufe... Handelt es
sich dann um eine statische Funktion die für beide Instanzen gleich ist
oder?
Gibt es zu dem ganzen Thema eine gute Literatur, wo man das nachlesen
kann?
LG
apr schrieb:> Christian J. schrieb:>> Gibt es zu dem ganzen Thema eine gute Literatur, wo man das nachlesen>> kann?>> Ein C++ Buch.
Sehe ich auch so. Bis hierhin sind das alles völlig grundlegende
C++-Fragen.
Christian J. schrieb:>> ClassA hat einen Konstruktur welcher einen u8 entgegen nimmt>
1
ClassAa=ClassA(2);oder
2
>ClassAa(2);
3
>
Grundsätzlich sollte man "dynamisches" vermeiden, was C++ nicht immer
offensichtlich macht.
1.Variante sollte ein Instanz a erzeugen (via Default Konstruktor), dann
eine dynamische Instanz, die durch Aufruf des =Operators auf a "kopiert"
wird.
2.Variante erzeugt a über den Konstruktor, der ein uint8_t erwartet.
Allerdings wird GCC im Fall 1 warscheinlich entdecken, daß das im
Ergebnis mit Fall 2 übereinstimmt und den Optimizer-Hobel ansetzen. Es
scheint dann so,als wäre das identisch.
Für C++ auf AVR ist es aber gut, wenn man den Unterschied versteht.
Carl Drexler schrieb:> Grundsätzlich sollte man "dynamisches" vermeiden, was C++ nicht immer> offensichtlich macht.
Da ist nichts dynamisches.
> 1.Variante sollte ein Instanz a erzeugen (via Default Konstruktor), dann> eine dynamische Instanz, die durch Aufruf des =Operators auf a "kopiert"> wird.
Nein.
> 2.Variante erzeugt a über den Konstruktor, der ein uint8_t erwartet.
Die Varianten sind gleich.
> Allerdings wird GCC im Fall 1 warscheinlich entdecken, daß das im> Ergebnis mit Fall 2 übereinstimmt und den Optimizer-Hobel ansetzen. Es> scheint dann so,als wäre das identisch.> Für C++ auf AVR ist es aber gut, wenn man den Unterschied versteht.
Nein. Es gibt hier keinen Unterschied. Das sind alles initializer. Da
wird nichts assigned.
apr schrieb:>> 1.Variante sollte ein Instanz a erzeugen (via Default Konstruktor), dann>> eine dynamische Instanz, die durch Aufruf des =Operators auf a "kopiert">> wird.> Nein.
und wieso nicht? ich sehe das genauso wie christian...
>>> 2.Variante erzeugt a über den Konstruktor, der ein uint8_t erwartet.> Die Varianten sind gleich.
im endeffekt durch den optimizer ja, rein programmier-logisch nicht
apr schrieb:>> Grundsätzlich sollte man "dynamisches" vermeiden, was C++ nicht immer>> offensichtlich macht.> Da ist nichts dynamisches.>>> 1.Variante sollte ein Instanz a erzeugen (via Default Konstruktor), dann>> eine dynamische Instanz, die durch Aufruf des =Operators auf a "kopiert">> wird.> Nein.>> 2.Variante erzeugt a über den Konstruktor, der ein uint8_t erwartet.> Die Varianten sind gleich.
Auch nein.
>> Allerdings wird GCC im Fall 1 warscheinlich entdecken, daß das im>> Ergebnis mit Fall 2 übereinstimmt und den Optimizer-Hobel ansetzen. Es>> scheint dann so,als wäre das identisch.>> Für C++ auf AVR ist es aber gut, wenn man den Unterschied versteht.> Nein. Es gibt hier keinen Unterschied.
Doch, den gibt es. Fall 1 erzeugt ein temporäres Objekt vom Typ ClassA
und erzeugt dann a per Copy-Kontruktor daraus. Fall 2 erzeugt a direkt.
Dem Compiler ist es allerdings gestattet, diese Copy-Konstruktion
wegzuoptimieren. Wenn der Copy-Konstruktor nicht aufrufbar ist, bekommst
du aber dennoch eine Fehlermeldung.
> Das sind alles initializer. Da wird nichts assigned.
Das ist richtig.
Yodaminator schrieb:> apr schrieb:>>> 1.Variante sollte ein Instanz a erzeugen (via Default Konstruktor),>>> dann eine dynamische Instanz, die durch Aufruf des =Operators auf a>>> "kopiert" wird.>> Nein.> und wieso nicht?
Weil da nirgends eine Zuweisung vorkommt.
1
TypName=Wert;
Das ist keine Zuweisung, sondern eine Definition einer Variablen mit
Initialisierung. Es wird kein Operator aufgerufen, sondern der
Konstruktor.
1
Name=Wert;
Das ist eine Zuweisung. Hier wird der operator = aufgerufen.
apr schrieb:> Nein. Es gibt hier keinen Unterschied. Das sind alles initializer. Da> wird nichts assigned.
Man kann das ruhig verallgemeinern:
Wird ein Objekt definiert
myClass b;
dann ist das eine Objekterzeugung. Die Erzeugung eines neuen Objektes
impliziert aber IMMER einen Aufruf eines Konstruktors (und zwar für
dieses Objekt von nur EINEM Konstruktor und sonst nichts anderes).
Immer. Eine eventuell angegebene Initialisierung, egal wie sie aussieht,
kann nur noch aus den vorhandenen Konstruktoren eine Auswahl treffen -
aber der Aufruf eines Konstruktors ist unabdingbar. Ein op= hat an
dieser Stelle überhaupt keine Daseinsberechtigung.
In C++ muss man ganz klar zwischen Initialisierung und Zuweisung
unterscheiden.
Initialisierung ... Aufruf eines entsprechenden Konstruktors, das
Objekt existierte vorher noch nicht
Zuweisung ... Aufruf des op=. Das Objekt existierte vorher
bereits, d.h. der op= muss sich auch um das
'Zerstören' des alten Objektinhaltes kümmern,
sofern es da etwas zu tun gibt.
Nicht jedes = ist eine Zuweisung. Bei der Erzeugung eines neuen Objektes
kann es keine Zuweisung geben, sondern das ist immer ein
Konstruktoraufruf und nicht mehr.
Carl Drexler schrieb:> Allerdings wird GCC im Fall 1 warscheinlich entdecken, daß das im> Ergebnis mit Fall 2 übereinstimmt und den Optimizer-Hobel ansetzen. Es> scheint dann so,als wäre das identisch.
Nicht nur das.
Wir reden hier von der sog. 'Named Return Value Optimization' bzw. in
neueren Standards die 'copy elision'. Jeder C++ Compiler, der auch nur
ansatzweise ernst genommen werden will, muss diese Optimierung
beherrschen.
Diese Optimierung ist für C++ so wichtig wie ein Schluck Wasser für
einen Ertrinkenden. Der Compiler würde ansonsten den Code mit der
Erzeugung von temporären Objekten regelrecht überfluten - speziell bei
Templates kommt diese Situation oft vor.
Immerhin wichtig genug, dass sie die einzige Optimierung ist, die im C++
Standard beschrieben und für die eine AUSNAHME von der 'As-If' Regel
gemacht wird. D.h. der Compiler muss nicht den Code des Copy
Construktors analysieren um festzustellen, ob dieser Nebeneffekte hat,
die über das reine Erzeugen einer Objektkopie hinausgehen. Sobald ein
Copy-Constructor im Spiel ist, darf der Compiler diese Optimierung
anwenden (und noch ein paar Nebenbedingungen technischer Natur), selbst
dann WENN der vom Programmierer geschrieben CCtor Nebeneffekte aufweist,
die durch die Optimierung wegfallen.
Daraus folgt: Es ist nicht schlau, Funktionalität in den CCtor
reinzulegen, die nichts mit dem Erzeugen einer Kopie zu tun hat. Wer
also seine Lichtorgel so aufbaut, dass bei jedem Aufruf des CCtor eine
Lampe umgeschaltet wird und er die Logik so aufbaut, dass die Lichtorgel
aus einem geordneten kopieren von Objekten besteht - der hat mit
Zitronen gehandelt.
Paul schrieb:> Für genau diese Fragen empfehle ich:> "Effective C++" von Scott Meyers
Jep.
Ein grundlegendes C++ Buch
Dann den Meyers
Und hinten nach noch "More effective C++" vom selben Autor
Und noch was grundlegendes über die STL (Nicolai Josuttis wurde früher
dafür immer gerne empfohlen)
dann hat man alles in seiner Bibliothek stehen, so dass einen so schnell
nichts mehr aus der Bahn wirft. Die Bücher aber auch lesen/durcharbeiten
und nicht nur ins Regal stellen. Speziell das grundlegende C++ Buch ist
für den Einstieg wichtig!
Wer dann immer noch nicht genug hat, der möge sich Literatur von 'Herb
Sutter' zulegen. Hochgradig empfohlen wenn es um die (oftmals gar nicht
so kleinen) Kleinigkeiten in der Sprache geht.
Für Ansätze und Ideen zur Objektorientierten Programmierung gäbe es dann
noch die sog. 'Gang of Four' - GOF -
http://en.wikipedia.org/wiki/Design_Patterns_(book)
(Bitte im Link die ) ergänzen - Fehler in der Forensoftware)
Wer sich in C++ fit genug fühlt und wirklich was lernen will, kann sich
ja mal durch Herb Sutters - "Guru of the Week" durcharbeiten. Herb hat
damit seit 1997 Millionen C++ Programmierern weltweit gezeigt, was C++
ist und wie man es korrekt verwendet um zum Profi zu werden. C++
Kentnisse werden vorausgesetzt - am Anfang weniger, zum Schluss schon
mehr. Herb hatte die jeweilige GotW Frage in einer Newsgroup gestellt,
dann lies er die Leser eine Woche lang diskutieren bis er dann seine
Sicht der Dinge veröffentlichte. Und genau so sollte man das auch
halten: Frage lesen - darüber nachdenken - Herbs Antwort dazu lesen.
http://www.gotw.ca/gotw/index.htm
Unten, beim ersten Eintrag anfangen!
Zb. behandelt GotW #1 genau den Fall der Initialisierung
http://www.gotw.ca/gotw/001.htm
Karl Heinz Buchegger schrieb:> Und hinten nach noch "More effective C++" vom selben Autor
Mit dem wunderschönen deutschen Titel: "Mehr effektiv C++ programmieren"
:-)
Aber man muss es eh auf Englisch lesen, schon alleine wegen dem coolen
Schreibstil des Autors. :-)