Kann mir bitte jemand einen Link zu einem verständlichen (mögl. deutschen) Tutorial geben, in dem beschrieben wird, wie man im Ardino-C++ (in der Arduino-IDE) eine funktionierende Klasse inkl. Construktor mit Parametern erstellt? Ich habe Erfahrungen (und bisher kein Problem) im Estellen von Klassen in Java, Processing und Xojo. Was ich bei meinem ersten Versuch aber diesbezüglich in der Arduino-IDE erlebt habe, hat mich echt zweifeln lassen. Ich bekam die (m.E.) absurdesten Fehlermekdungen angezeigt. Wer hat sich das bloß ausgedacht ... ? Ach ja: Danke für Tips.
Frank E. schrieb: > wie man im Ardino-C++ "Ardino-C++" gibt es nicht, dass ist ganz stink "normales" C++ mit GCC als toolchain im Hintergrund. Du kannst also jeder x-beliebige Beschreibung zu dem Thema nutzen die du im I-Net zu tausenden findest. Z.B.: https://en.cppreference.com/w/cpp/language/class http://www.cplusplus.com/doc/tutorial/classes/
Irgend W. schrieb: > "Ardino-C++" gibt es nicht, dass ist ganz stink "normales" C++ mit GCC > als toolchain im Hintergrund. > Du kannst also jeder x-beliebige Beschreibung zu dem Thema nutzen die du > im I-Net zu tausenden findest. > Z.B.: > https://en.cppreference.com/w/cpp/language/class > http://www.cplusplus.com/doc/tutorial/classes/ Bedenke jedoch, dass die Std lib nicht zur Verfügung steht.
:
Bearbeitet durch User
Frank E. schrieb: > Ich bekam die (m.E.) absurdesten Fehlermekdungen angezeigt. Du kannst auch mal hier posten, was du versucht hast, und welche "absurde" Meldung du dann bekommen hast. Dann kann dir bestimmt jemand erklären, was falsch ist und warum der Compiler nun gerade so darauf reagiert hat.
hier habe ich ein Beispiel mit einer Klasse für ein Relais, wo der Pin mittels Initialisierungsliste im Konstruktor übergeben wird: https://werner.rothschopf.net/202003_arduino_retriggerbares_nachlaufrelais_oop.htm
noiasca schrieb: > hier habe ich ein Beispiel mit einer Klasse für ein Relais, wo der > Pin > mittels Initialisierungsliste im Konstruktor übergeben wird: > > https://werner.rothschopf.net/202003_arduino_retriggerbares_nachlaufrelais_oop.htm DAS sieht sehr gut aus! Einen Constructor SO zu schreiben, darauf wäre ich (aufgrund meiner bescheidenen Java-Erfahrungen) nie im Leben gekommen. Ich habe auch nirgendwo so ein schönes Beispiel gesehen. Die meisten Dokus machen sowas durch Darstellung aller möglichen Optionen völlig unverständlich. Eine Doku ist eben kein Lehrbuch. Na gut ... Bei den sonstigen Methoden wie Setter/Getter ist das ja nicht so drastisch ... sicher hätte ich es mir irgendwann angelesen ... Danke.
1 | retriggerOffDelay(byte buttonPin, byte outputPin) : // the constructor |
2 | buttonPin(buttonPin), |
3 | outputPin(outputPin) |
4 | {} |
:
Bearbeitet durch User
Frank E. schrieb: > Einen Constructor SO zu schreiben, darauf wäre ich (aufgrund meiner > bescheidenen Java-Erfahrungen) nie im Leben gekommen. Wer gedacht, dass java != C++ ist? Wie hättest du es denn in java gemacht?
mh schrieb: > Frank E. schrieb: >> Einen Constructor SO zu schreiben, darauf wäre ich (aufgrund meiner >> bescheidenen Java-Erfahrungen) nie im Leben gekommen. > > Wer gedacht, dass java != C++ ist? Wie hättest du es denn in java > gemacht? Na als "scheinbar" ganz normale Methode aber ohne Rückgabe, auch kein Void, mit dem gleichen Namen wie die Klasse. Bei Bedarf in Varianten mit unterschiedlicher Anzahl von Parametern ... Dass man in C++ beim Instanziieren nicht "new" verwendet, darauf war ich schon alleine gekommen :-)
:
Bearbeitet durch User
mh schrieb: > Frank E. schrieb: >> Einen Constructor SO zu schreiben, darauf wäre ich (aufgrund meiner >> bescheidenen Java-Erfahrungen) nie im Leben gekommen. > > Wer gedacht, dass java != C++ ist? Wie hättest du es denn in java > gemacht? Frank E. schrieb: > Na als "scheinbar" ganz normale Methode aber ohne Rückgabe, auch kein > Void, mit dem gleichen Namen wie die Klasse. Bei Bedarf in Varianten mit > unterschiedlicher Anzahl von Parametern ... Wo genau ist da jetzt der unterschied zu C++?
Frank E. schrieb: > Dass man in C++ beim Instanziieren nicht "new" verwendet, darauf war ich > schon alleine gekommen :-) Du darfst new verwenden wenn du das Objekt auf dem Heap haben willst, ansonste wird das Objekt auf dem Stack angelegt
Frank E. schrieb: > Na als "scheinbar" ganz normale Methode aber ohne Rückgabe, auch kein > Void, mit dem gleichen Namen wie die Klasse. Bei Bedarf in Varianten mit > unterschiedlicher Anzahl von Parametern ... Ist in Java exakt gleich, ohne Rückgabe und n Varianten mit unterschiedlichen Parametern
mh schrieb: > mh schrieb: >> Frank E. schrieb: >>> Einen Constructor SO zu schreiben, darauf wäre ich (aufgrund meiner >>> bescheidenen Java-Erfahrungen) nie im Leben gekommen. >> >> Wer gedacht, dass java != C++ ist? Wie hättest du es denn in java >> gemacht? > > Frank E. schrieb: >> Na als "scheinbar" ganz normale Methode aber ohne Rückgabe, auch kein >> Void, mit dem gleichen Namen wie die Klasse. Bei Bedarf in Varianten mit >> unterschiedlicher Anzahl von Parametern ... > Wo genau ist da jetzt der unterschied zu C++? Einen Unterschied gibt es in C++ noch: Man verwendet Initialisierungslisten.
Rolf M. schrieb: > Einen Unterschied gibt es in C++ noch: Man verwendet > Initialisierungslisten. Man kann sie verwenden, niemand zwingt einen dazu.
mh schrieb: > Frank E. schrieb: >> Na als "scheinbar" ganz normale Methode aber ohne Rückgabe, auch kein >> Void, mit dem gleichen Namen wie die Klasse. Bei Bedarf in Varianten mit >> unterschiedlicher Anzahl von Parametern ... > Wo genau ist da jetzt der unterschied zu C++? Na dann guck dir doch mal mein Code-Zitat von 12:17 an: - Doppelpunkt nach dem Funktionskopf - zwei (scheinbare) Methodenaufrufe mit dem gleichen Namen wie die Parameter - ein leeres Paar geschweifte Klammern ... Kann man mit Sicherheit alles logisch erklären, für mich war es aber erstaunlich fremd, fremder jedenfalls als Java. Ist aber auch egal, ich habs zwar noch nicht völlig verstanden, kann es aber anwenden. Der Rest kommt sicher im Laufe der Zeit.
mh schrieb: > Man kann sie verwenden, niemand zwingt einen dazu. Ist aber besser, weil man dann auch constexpr nutzen kann und die Variablen nie einen uninitialisierten Zustand haben. Wie man Klassen in C++ implementiert steht in jedem C++-Buch. In ein solches zu schauen ist hier sowieso eine gute Idee, da Arduino-Tutorials vieles verkürzt, vereinfacht oder gar falsch darstellen. C++ ist komplex und hat viele Fallstricke, weshalb man das am Besten konsequent mit einem Buch lernt, z.B.: https://stackoverflow.com/a/388282
Programmierer schrieb: > mh schrieb: >> Man kann sie verwenden, niemand zwingt einen dazu. > > Ist aber besser, weil man dann auch constexpr nutzen kann und die > Variablen nie einen uninitialisierten Zustand haben. Klar ist das besser, auch wenn deine Begründung unvollständig und nicht unbeding richtig ist. Aber wenn der TO seinen Constructor auf Java-Art schreiben möchte kann er das machen. Es zwingt ihn niemand, Initialisierungslisten zu verwenden. Frank E. schrieb: > mh schrieb: > >> Frank E. schrieb: >>> Na als "scheinbar" ganz normale Methode aber ohne Rückgabe, auch kein >>> Void, mit dem gleichen Namen wie die Klasse. Bei Bedarf in Varianten mit >>> unterschiedlicher Anzahl von Parametern ... >> Wo genau ist da jetzt der unterschied zu C++? > > Na dann guck dir doch mal mein Code-Zitat von 12:17 an: > [...] Und warum hast du ihn nicht auf Java-Art geschrieben? Was war da dein Problem?
Frank E. schrieb: > Bei den sonstigen Methoden wie Setter/Getter ist das ja nicht so > drastisch ... sicher hätte ich es mir irgendwann angelesen ... Danke. > retriggerOffDelay(byte buttonPin, byte outputPin) : // the constructor > buttonPin(buttonPin), > outputPin(outputPin) > {} Und glaube keinen beliebigen Internetquellen, denn das verlinkte ist in der Tat falsch - man achte auf die Schreibweise ;-) Und wer neben einem vermeintlichen CTor dann noch so einen Kommentar schreibt, dem sollte man besser aus dem Weg gehen. Nimm ein C++ Buch wie den Breymann und mache es Dir auf der Couch gemütlich.
:
Bearbeitet durch User
mh schrieb: > Rolf M. schrieb: >> Einen Unterschied gibt es in C++ noch: Man verwendet >> Initialisierungslisten. > Man kann sie verwenden, niemand zwingt einen dazu. Das kommt auf den Anwendungsfall an. Man sollte sie in der Regel verwenden, manchmal muss man sie auch zwingend verwenden, z.B. wenn man ein Objekt einer Klasse erstellen will, die keinen Default-Konstruktor hat. Es muss einem eben auch klar sein, dass Initialisierung und Zuweisung zwei unterschiedliche Dinge sind, die sich unterschiedlich auswirken können. Aber ja, oft geht auch der Umweg über eine Default-Initialisierung mit nachfolgender Zuweisung statt einer direkten Initialisierung.
:
Bearbeitet durch User
Rolf M. schrieb: > Das kommt auf den Anwendungsfall an. Man sollte sie in der Regel > verwenden, manchmal muss man sie auch zwingend verwenden, z.B. wenn man > ein Objekt einer Klasse erstellen will, die keinen Default-Konstruktor > hat. Ein Objekt eines Typs ohne Std-CTor kann ich auch über einen Elementinitialisierer initialisieren.
Rolf M. schrieb: > Aber ja, oft geht auch der Umweg über eine Default-Initialisierung mit > nachfolgender Zuweisung statt einer direkten Initialisierung. Und genauso oft nicht! Es soll DT geben, die nicht kopierzuweisbar sind ;-)
Wilhelm M. schrieb: > Ein Objekt eines Typs ohne Std-CTor kann ich auch über einen > Elementinitialisierer initialisieren. Ja, kann man heute auch machen, sofern keiner der Konstruktor-Parameter wiederum von Konstruktor-Parametern des äußeren Objekts abhängt. Ich hatte das nicht erwähnt, weil ich's nicht unnötig kompliziert machen wollte. Spielt ja an sich auch keine Rolle für die Frage, warum man Initialisierungslisten gegenüber Zuweisungen und ähnlichem innerhalb des Konstruktors vorziehen sollte. Wilhelm M. schrieb: > Rolf M. schrieb: >> Aber ja, oft geht auch der Umweg über eine Default-Initialisierung mit >> nachfolgender Zuweisung statt einer direkten Initialisierung. > > Und genauso oft nicht! > Es soll DT geben, die nicht kopierzuweisbar sind ;-) Hab doch geschrieben, dass es je nach Fall gehen kann oder auch nicht.
:
Bearbeitet durch User
Rolf M. schrieb: > Ja, kann man heute auch machen, Nein, das ging schon immer. Was Du meinst sind die in-class-initializer in brace-or-equal-form.
Wilhelm M. schrieb: > Rolf M. schrieb: >> Ja, kann man heute auch machen, > > Nein, das ging schon immer. > Was Du meinst sind die in-class-initializer in brace-or-equal-form. Dann weiß ich nicht, was du meinst. Ich kenne außer per initializer list und in-class keine Möglichkeit, eine Membervariable explizit zu initialisieren.
:
Bearbeitet durch User
Das meine ich:
1 | struct A { |
2 | A(int a) : m{a}{} // Element-Initialisierungslist mit Elementinitialisierer |
3 | int m = 42; // in-class Element-Initialisierung (value-init in equal-form) |
4 | int o{[]{return 42;}()}; // in-class Element-Initialisierung (value-init in brace-form) |
5 | };
|
Wilhelm M. schrieb: > A(int a) : m{a}{} // Element-Initialisierungslist mit > Elementinitialisierer Aber wir sprachen doch von einer Initialisierung ohne Initialisierungsliste. Also so:
1 | struct A |
2 | {
|
3 | A(int) {} |
4 | };
|
5 | |
6 | struct B |
7 | {
|
8 | B(int x) |
9 | {
|
10 | /* Initialisierung von a mit übergebenem Wert
|
11 | aber ohne Initialisierungsliste */
|
12 | }
|
13 | |
14 | A a; |
15 | }
|
Und ich wüsste nicht, wie das gehen soll.
:
Bearbeitet durch User
Rolf M. schrieb: > Aber wir sprachen doch von einer Initialisierung ohne > Initialisierungsliste. Ja, das habe ich Dir gezeigt. Das mit dem ctor-Parameter hast Du jetzt hinzugefügt. Ich habe nur oben gesagt, dass es eben DT geben kann, die vllt. nicht kopier/verschiebungszuweisbar sind. Mag alles ein großes Missverständnis zu sein...
Wilhelm M. schrieb: > Rolf M. schrieb: >> Aber wir sprachen doch von einer Initialisierung ohne >> Initialisierungsliste. > > Ja, das habe ich Dir gezeigt. Es tut mir leid, aber ich weiß echt nicht, worauf du hinaus willst. > Das mit dem ctor-Parameter hast Du jetzt hinzugefügt. Das hatte ich nur gemacht, damit ich die in-Class-Initialisierung als zweite Option nicht nochmal explizit erwähnen muss. Du hast dafür übrigens int statt einer Klasse ohne Default-Konstruktor verwendet. > Ich habe nur oben gesagt, dass es eben DT geben kann, die vllt. nicht > kopier/verschiebungszuweisbar sind. Und ich schrieb, dass man für eine Klasse ohne Default-Konstruktor die Initialisierungsliste braucht. Darauf meintest du, dass es auch über einen "Elementinitialisierer" ginge. Ich war davon ausgegangen, das du damit in-Class-Initialisierung meinst, was du verneint hast. Also bin ich davon ausgegangen, dass du eine dritte, mir unbekannte Art meinst, die weder in-Class, noch per Initialisierungsliste passiert. Dein Beispiel zeigt aber jetzt nur einmal per Initialisierungsliste und zweimal in-Class. > Mag alles ein großes Missverständnis zu sein... Vermutlich.
:
Bearbeitet durch User
Rolf M. schrieb: > Und ich schrieb, dass man für eine Klasse ohne Default-Konstruktor die > Initialisierungsliste braucht. Dann mache dazu mal ein Beispiel.
Wilhelm M. schrieb: > Dann mache dazu mal ein Beispiel.
1 | class X { |
2 | public:
|
3 | X () {} |
4 | int& ref; |
5 | };
|
Resultiert in Compiler-Fehler. Man braucht
1 | class X { |
2 | public:
|
3 | X () {} |
4 | int y; |
5 | int& ref { y }; |
6 | };
|
oder
1 | class X { |
2 | public:
|
3 | X () : ref {y} {} |
4 | int y; |
5 | int& ref; |
6 | };
|
Einen dritten Weg gibt es nicht. Insbesondere geht auch so etwas wie
1 | class X { |
2 | public:
|
3 | X () { ref = y; } |
4 | int y; |
5 | int& ref; |
6 | };
|
nicht, und macht auch überhaupt keinen Sinn (Referenzen selbst sind nicht zuweisbar).
Niklas G. schrieb: > Wilhelm M. schrieb: >> Dann mache dazu mal ein Beispiel. > class X { > public: > X () {} > int& ref; > }; Das ist klar. Er schrieb: ein DT ohne Std-ctor(!) kann nur über die Elementinit-liste initialisiert werden. Als es geht um die Eigenschaft: Std-ctor ja oder nein. Nicht das was Du geschrieben hast.
Wilhelm M. schrieb: > Rolf M. schrieb: >> Und ich schrieb, dass man für eine Klasse ohne Default-Konstruktor die >> Initialisierungsliste braucht. > > Dann mache dazu mal ein Beispiel. ?? Das hab ich doch gerade in Beitrag "Re: Klasse in Arduino-C++" getan.
Wilhelm M. schrieb: > Als es geht um die Eigenschaft: Std-ctor ja oder > nein. "int&" hat keinen Standard-CTor. Somit bleiben eben diese beiden Möglichkeiten - Initialisierungsliste im Konstruktor oder In-Class-Initialization. Eine Initialisierungsliste ohne Konstruktor gibt es in C++ nicht (in anderen Sprachen wie Scala oder Kotlin schon).
1 | struct A |
2 | {
|
3 | A(int) {} |
4 | };
|
5 | struct B |
6 | {
|
7 | B(int x) |
8 | {
|
9 | }
|
10 | A a{42}; |
11 | }
|
Geht doch.
Wilhelm M. schrieb: > Geht doch. Das ist die in-Class-Initialisierung und keine Initializer-Liste. Also eine der beiden(!) genannten Möglichkeiten.
:
Bearbeitet durch User
Niklas G. schrieb: > Das ist die in-Class-Initialisierung und keine Initializer-Liste. Also > eine der beiden genannten Möglichkeiten. Das sage ich doch die ganze Zeit. Nur Rolf behauptet, das eine in-class init für einen DT ohne std-ctor nicht geht. Der DT int hat auch einen std-ctor. Es ging nicht um Referenzen, das hast Du erst ins Spiel gebracht.
Wilhelm M. schrieb: > Niklas G. schrieb: >> Das ist die in-Class-Initialisierung und keine Initializer-Liste. Also >> eine der beiden genannten Möglichkeiten. > > Das sage ich doch die ganze Zeit. > Nur Rolf behauptet, das eine in-class init für einen DT ohne std-ctor > nicht geht. Hä? Das hab ich nie behauptet. Das Gegenteil davon habe ich hier geschrieben: Rolf M. schrieb: > Wilhelm M. schrieb: >> Ein Objekt eines Typs ohne Std-CTor kann ich auch über einen >> Elementinitialisierer initialisieren. > > Ja, kann man heute auch machen, sofern keiner der Konstruktor-Parameter > wiederum von Konstruktor-Parametern des äußeren Objekts abhängt. Darauf hast du geantwortet: Wilhelm M. schrieb: > Nein, das ging schon immer. > Was Du meinst sind die in-class-initializer in brace-or-equal-form. … und genau die meinte ich auch. Du hast die aber anscheinend nicht gemeint, deswegen wollte ich wissen, was du denn dann meintest. Wilhelm M. schrieb: > Geht doch. Das ist immer noch keine Klasse ohne Default-Konstruktor, sondern int. Damit ging das tatsächlich schon immer. Instanzen von Klassen kann man aber erst seit C++11 in-class initialisieren.
:
Bearbeitet durch User
Rolf M. schrieb: > Und ich schrieb, dass man für eine Klasse ohne Default-Konstruktor die > Initialisierungsliste braucht Das hast Du geschrieben. Aber das ist ja nicht zwingend: wie ich Dir gezeigt habe, kann man einen DT ohne std-ctor auch in-class mit einem allg. ctor initialisieren.
Wilhelm M. schrieb: > Rolf M. schrieb: >> Und ich schrieb, dass man für eine Klasse ohne Default-Konstruktor die >> Initialisierungsliste braucht > > Das hast Du geschrieben. Ja, das habe ich geschrieben. Darauf hast du die in-class-Initialisierung erwähnt, was ich dann bestätigt habe. Siehe obiges zitiertes Posting von mir. Hier nochmal: Rolf M. schrieb: > Ja, kann man heute auch machen, sofern keiner der Konstruktor-Parameter > wiederum von Konstruktor-Parametern des äußeren Objekts abhängt. Du hast dann geschrieben, das ginge schon immer, aber das geht erst seit C++11. > Aber das ist ja nicht zwingend: wie ich Dir gezeigt habe, kann man einen > DT ohne std-ctor auch in-class mit einem allg. ctor initialisieren. Das habe ich nie bestritten.
:
Bearbeitet durch User
Wilhelm M. schrieb: > Rolf M. schrieb: >> Und ich schrieb, dass man für eine Klasse ohne Default-Konstruktor die >> Initialisierungsliste braucht > > Das hast Du geschrieben. > Aber das ist ja nicht zwingend: wie ich Dir gezeigt habe, kann man einen > DT ohne std-ctor auch in-class mit einem allg. ctor initialisieren. Mensch so schwer ist das doch nicht. es Geht Rolf die ganze Zeit um eine Klasse mit Member ohne default-ctor und nicht um eine Klasse ohne default-ctor.
mh schrieb: > Geht Rolf die ganze Zeit um eine > Klasse mit Member ohne default-ctor und nicht um eine Klasse ohne > default-ctor. ???
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.