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.
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).
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.
EAF schrieb:> Wenn sich der Compiler über eine fehlender Definition beschwert, dann> ist auch anzunehmen, dass diese benötigt wird.>>
1
>classMyClass
2
>{
3
>public:
4
>uint8_tvar;
5
>staticuint8_ttest;
6
>};
7
>
8
>inlineuint8_tMyClass::test;
9
>
10
>intmain()
11
>{
12
>uint8_tlala=0;
13
>MyClassMyObject;
14
>MyObject.var=10;
15
>MyClass::test=2;// ==> leads to error
16
>return0;
17
>}
18
>
> *ungetestet*
In der Tat.
So geht es:
1
classMyClass
2
{
3
public:
4
uint8_tvar{0};
5
inlinestaticuint8_ttest{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.
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.
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang