Guten Tag, nachdem ich mich mit folgendem Problem jetzt schon eine Weile herumschlage wollte ich endlich mal Klarheit schaffen. Offensichtlich habe ich noch Lücken in meinem "Class"-Verständnis die ich überwinden sollte. Hier das Problem: //================ Main (main.cpp) ============================ #include <stdio.h> class MyClass { public: uint8_t var; static uint8_t test; }; int main() { uint8_t lala = 0; MyClass MyObject; MyObject.var = 10; MyClass::test = 2; // ==> leads to error return 0; } //============================================================ Wenn ich die Zeile "MyClass::test = 2; " auskommentiere läuft alles wie gewünscht, im obigen Zustand krieg ich aber folgende Fehlermeldung: "Main.cpp:(.text.main+0x4): undefined reference to `MyClass::test'" Irgendwas läuft also wegen der "static"-Definition von "uint8_t test" schief. Als Compiler nutze ich avr-g++ in MPLAB (unter Ubuntu). Hätte mir jemand ein Tip was ich da falsch mache bzw. wie ich statische Klassenvariable richtig definieren muß damit es klappt ? Vielen Dank, Hermann Ps: Aus Gründen die mir nicht klar sind wirbelt die Formatierung der Webseite mein Programm unansehnlich durcheinander, bitte dafür um Entschuldigung.
Wenn sich der Compiler über eine fehlender Definition beschwert, dann ist auch anzunehmen, dass diese benötigt wird.
1 | class MyClass |
2 | {
|
3 | public:
|
4 | uint8_t var; |
5 | static uint8_t test; |
6 | };
|
7 | |
8 | inline uint8_t MyClass::test; |
9 | |
10 | int main() |
11 | {
|
12 | uint8_t lala = 0; |
13 | MyClass MyObject; |
14 | MyObject.var = 10; |
15 | MyClass::test = 2; // ==> leads to error |
16 | return 0; |
17 | }
|
ungetestet Übrigens Statische Klassen Eigenschaften sind in der Regel böse.
Hermann E. schrieb: > Hätte mir jemand ein Tip was ich da falsch mache bzw. wie ich statische > Klassenvariable richtig definieren muß damit es klappt ? https://www.geeksforgeeks.org/static-data-members-c/
1 | The above program calls only B’s constructor, it doesn’t call A’s constructor. The reason for this is simple, static members are only declared in a class declaration, not defined. They must be explicitly defined outside the class using the scope resolution operator. |
Supa ! War gerade Essen, so dass ich eure Beiträge nicht gleich gesehen habe. Die Sache mit dem "Inline" hat leider so nicht geklappt, mir war auch offen gestanden nicht ganz klar warum dies funktionieren sollte. Dennoch Danke für den Tip, ich schätze jede ernstgemeinte Hilfe auch wenn es nicht immer zum Ziel führt. Letztlich war im von Mani vorgeschlagenen Artikel: https://www.geeksforgeeks.org/static-data-members-c/ der entscheidende Satz zu finden: "static members are only declared in a class declaration, not defined. They must be explicitly defined outside the class using the scope resolution operator." Also: #include <stdio.h> class MyClass { public: uint8_t var; static uint8_t test; }; uint8_t MyClass::test; int main() { uint8_t lala = 0; MyClass MyObject; MyObject.var = 10; MyClass::test = 2; // ==> leads to error return 0; } mit der zusätzlichen (out of Scope) Zeile: "uint8_t MyClass::test;" lässt den Compiler fehlerfrei durchlaufen. Danke, Hermann
Hermann E. schrieb: > Die Sache mit dem "Inline" hat leider so nicht geklappt, Dann verwendest du eine veraltete C++ Variante. Und ja, in dem Beispiel macht das inline keinen Vorteil. Aber es ermöglicht die Unterbringung in *.h only Dateien, ohne weitere Klimmzüge. Hermann E. schrieb: > mir war auch > offen gestanden nicht ganz klar warum dies funktionieren sollte. Wie wäre es mit einem schönen dicken und modernen C++ Grundlagenbuch?
"Dann verwendest du eine veraltete C++ Variante." Hatte mehrere Tage damit verwendet einen neueren Compiler zu installieren bin dann aber in andere Probleme geraten und irgendwann wird's dem Hobbyanwender(!) dann zu dumm... Nur so: Ein menschliches Leben macht im Schnitt ca. 30kTage, ein Monat sind schon 1 Promille, da sollte man Prioritäten setzen. ----------------------------------------------------------------------- "Wie wäre es mit einem schönen dicken und modernen C++ Grundlagenbuch?" Grob abgeschätzt enthält ein "dickes und modernes C++ Grundlagenbuch" so ca. 10000 Informationselemente die man wissen müsste um C(++) perfekt (?) zu beherrschen. Auch wenn Du nur eines davon entgangen ist, kann es früher oder später dazu führen, dass Du dir genau daran die Nase blutig stösst. Dann gibt es zwei Möglichkeiten: Entweder man liest das "dicke und moderne C++ Grundlagenbuch" noch einmal oder... Jedenfalls: Bevor ich meine Frage gepostet hatte, waren schon mehrere Stunden in ehrlicher Suche nach (m)einer Lösung flöten gegangen. Ich spreche mehrere Fremdsprachen, aber ich wäre wohl nie weit gekommen, wenn ich mir vorgenommen hätte, eine neue Sprache erst dann zu verwenden, wenn ich sie perfekt beherrsche (also nie).
:
Bearbeitet durch User
Hermann E. schrieb: > Ich spreche mehrere Fremdsprachen, aber ich wäre wohl nie weit gekommen, > wenn ich mir vorgenommen hätte, eine neue Sprache erst dann zu > verwenden, wenn ich sie perfekt beherrsche (also nie). Du musstest sie aber trotzdem lernen. Das muss man auch mit Programmiersprachen tun, wenn man halbwegs ernsthaft etwas damit tun möchte. Wobei bei Programmiersprachen zu beachten ist, dass es extrem mühsam ist, sie nur per trial&error und Nachfragen in Foren zu erlernen. Man braucht ohne entsprechende Literatur nicht weniger, sondern mehr Lebenszeit, um die Sprache gewinnbringend einsetzen zu können. Und da spreche ich aus eigener Erfahrung. Hermann E. schrieb: > Jedenfalls: Bevor ich meine Frage gepostet hatte, waren schon mehrere > Stunden in ehrlicher Suche nach (m)einer Lösung flöten gegangen. Genau das meine ich damit. Das Problem, mit dem du dich jetzt mehrere Stunden herumgeschlagen hast, ist ein sehr grundlegendes Thema.
:
Bearbeitet durch User
EAF schrieb: > Wenn sich der Compiler über eine fehlender Definition beschwert, dann > ist auch anzunehmen, dass diese benötigt wird. > >
1 | > class MyClass |
2 | > { |
3 | > public: |
4 | > uint8_t var; |
5 | > static uint8_t test; |
6 | > }; |
7 | >
|
8 | > inline uint8_t MyClass::test; |
9 | >
|
10 | > int main() |
11 | > { |
12 | > uint8_t lala = 0; |
13 | > MyClass MyObject; |
14 | > MyObject.var = 10; |
15 | > MyClass::test = 2; // ==> leads to error |
16 | > return 0; |
17 | > } |
18 | >
|
> *ungetestet*
In der Tat.
So geht es:
1 | class MyClass |
2 | {
|
3 | public:
|
4 | uint8_t var{0}; |
5 | inline static uint8_t test{0}; |
6 | };
|
Man muss dann aber auch den C++-Standard entsprechend setzen und ein
nicht gar so grottenalten Compiler benutzen.
> Übrigens Statische Klassen Eigenschaften sind in der Regel böse.
Nein.
Es gibt sogar sinnvolle Muster damit.
Ich programmiere jetzt 25 Jahre mit C++. Aber manche Feinheiten und Neuerungen bekommt man trotzdem nicht mit, und muss selber noch mal nachlesen. Von daher finde ich es legitim, wenn ein Hobbyist spezielle Sachen noch einmal nachfragt. Und die Änderungen gerade in dem Bereich zeigen, dass ältere Versionen nicht unbedingt konsistent und verständlich waren.
Beitrag #7328354 wurde vom Autor gelöscht.
EAF schrieb: > Wilhelm M. schrieb: >> sinnvolle Muster > Ja! > Das Singleton Muster. Nun, ein Singleton ist ein Beispiel von vielen dafür, bspw. um einen globalen Zustand zu kapseln... > (Welches Kotzreiz verursacht) ... daher sollte es (richtig angewendet) auch nicht zu Unwohlsein führen. An vielen Stellen wird auch ein Monostate dafür eingesetzt. Beide tun im Prinzip dasselbe (einen globalen Zustand kapseln): das Singleton ist eher ein strukturelles Muster während das Monostate ein Verhaltensmuster ist. Gerade im µC Bereich gibt es zudem sehr sinnvolle Anwendungen von all-static templates/Klassen.
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.