Anfängerproblem: error LNK2001 bei einfacher statischer Variablen



  • Moin,
    Seit Tagen schlage ich mich nun mit einem LNK2001 in c++ herum, nachdem ich für die Uni c++ lernen muss.

    Fehler: » A.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: static float A::aVar" (?aVar@A@@2MA)". «

    Eigentlich sehe ich das Problem nicht, aber evtl ist es ja ganz einfach?

    //A.h
    class A
    {
    public:
        static float A::aVar;
    }
    
    //A.cpp
    #include "A.h"
    
    A::A()
    {
        A::aVar; //LNK2001
    }
    
    A::~A(){}
    

    Das ganze ist jetzt natürlich entsprechend vereinfacht, da ich hier ein Plugin umzuschreiben versuche, wo schon ne Menge infos drin stehen, die hier aber nix zur Sache tun. static muss aVar sein, weil ich aus einer statischen Funktion darauf zugreifen will. Wenn ich also so auf A::aVar zugreifen will wie oben beschrieben bekomme ich den LNK2001, wenn ich ne Referenz mache ebenfalls und bei nem Pointer meckert der Compiler wegen ner ungültigen Dereferenzierung rum...

    Daran, dass aVar nicht initialisiert ist kann es eigentlich auch nicht liegen, da der Versuch zu iitialisieren sowohl in der cpp-Datei (linker error) als auch in der h (error C2864: Nur statische konstante integrale Datenmember können innerhalb einer Klasse initialisiert werden) Fehler wirft...

    Ich hab mir schon verschiedene Tutorials/Bücher (z.B. Thinking in c++) angesehen, aber das hat nicht wirklich weiter geholfen und jetzt bin ich langsam verzweifelt...

    In Java ist sowas immer so leicht...

    Hat da jemand ne Idee, woran der Fehler liegen könnte?



  • huhu,
    du hast 3Fehler:

    1. Die Definition einer Klasse wird mit einem ";" beendet.

    2. Konstruktur ist nur für objektzugehörige Attribute zu haben, und nicht für klassenzugehörige (statische) Attribute. Nur statische-Methoden können auf statische Attribute zugreifen.

    3. Wenn du Methoden außerhalb der Klasse definierst, dann musst du sie davor schon in der Klasse deklarieren.

    #include <iostream>
    using namespace std;
    
    class A
    {
        public:
            static float aVar;
            A();
            ~A();
    };
    
    A::A(){}
    
    float A::aVar = 1234;
    
    A::~A(){} 
    
    int main()
    { 
        system("pause>nul");
        return 0;
    }
    


  • Schon mal danke für die Antwort, auch wenn sie mich leider nicht wirklich weiter bringt...

    Das ; war mein Fehler - vergessen mit abzuschreiben, genauso wie die Deklaration von Konstruktor und Destruktor.

    Mein eigentlicher Fehler lag also darin, dass deine Zeile 15 (also die Neudeklaration) gefehlt hatte.

    Damit funzt's soweit. Wenn ich das jetzt noch in's große Ganze eingebaut bekomme, dann bist du mein großer Retter...

    Das heißt jetzt geht der richtig große Spaß für mich los 😉

    Danke



  • ignoriere die erste Zeile - die hatte ich geschrieben, bevor ich verstanden hatte, wo das Problem lag...

    Man sollte genauer lesen, was man schreibt, wenn man nicht editieren kann XD



  • sefie schrieb:

    Das ; war mein Fehler - vergessen mit abzuschreiben, genauso wie die Deklaration von Konstruktor und Destruktor.

    ⚠ Niemals Code abschreiben! Immer Copy&Paste anwenden, um genau solche Flüchtigkeitsfehler zu vermeiden, die dann die Hilfesteller auf eine falsche Fährte locken oder zumindest unnötig mit "falschen Fehlern" beschäftigen! ⚠



  • sefie schrieb:

    Mein eigentlicher Fehler lag also darin, dass deine Zeile 15 (also die Neudeklaration) gefehlt hatte.

    Verwende bitte die richtige Terminologie.

    class A;  // <-- Deklaration der Klasse A
    
    class A { // <-- Definition  der Klasse A
    public:
      static int foo; // <-- Deklaration von A::foo
      int x;
    };
    
    int A::foo;       // <-- Definition von A::foo
    
    void bar(A*);     // <-- Deklaration einer Funktion
    
    void bar(A* a) {  // <-- Definition einer Funktion
      a->x=99;
    }
    

    Stell sicher, dass Du den Unterschied zwischen Deklaration und Definition kennst.

    kk



  • Dweb schrieb:

    1. Konstruktur ist nur für objektzugehörige Attribute zu haben, und nicht für klassenzugehörige (statische) Attribute. Nur statische-Methoden können auf statische Attribute zugreifen.

    Das stimmt nicht. Die Aussage muss lauten:

    Statische Methoden können nur auf statische Member zugreifen.

    Nichtstatische Member können sowohl auf statische als auch auf nicht-statische Member zufreifen.



  • Tachyon schrieb:

    Nichtstatische Member können sowohl auf statische als auch auf nicht-statische Member zufreifen.

    Genau das war auch meine ursprüngliche Intention.
    Ich habe nämlich eine dynamische Eingabe (Position einer Cursor-Instanz auf dem Bildschirm) und diese soll einen Render-Prozess beeinflussen, der hauptsächlich über statische Methoden abläuft.

    Ich hab's jetzt so gelöst, dass ich die statische Variable in der cpp-Datei deklariere und kurz vor Beginn des Renderprozesses (noch in einer non-static Funktion) mit den neusten Werten des Cursors "von Hand" überschreibe, so dass ich sie dann statisch parat habe. Nicht performant, aber es funzt soweit. Mehr wird von mir nicht erwartet.

    Und mir war schon klar, was der Unterschied zwischen Deklaration (Bekanntmachung) und Definition (Implementierung) ist, aber bei Variablen ist das ja schwimmend... Zumindest, wenn man das Initialisieren nicht als Definition wertet.

    Auf jeden Fall vielen Dank für eure Hilfe. Ich hab mir darüber buchstäblich Tage lang den Kopf zerbrochen und jetzt kann ich endlich weiter arbeiten.



  • sefie schrieb:

    Fehler: » A.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: static float A::aVar" (?aVar@A@@2MA)". «

    Ich hoffe meine Frage klingt jetzt nicht zu überheblich, aber es interessiert mich einfach:

    Was ist an der Fehlermeldung so schwer zu verstehen?

    Es sagt ganz klar, was der Linker vermisst hat. Und wenn ich zwar die Deklaration sehe und ich mir nicht sicher bin, ob das reicht, schaue ich doch als erstes in mein C++-Lehrbuch, um zu schauen, wie statische Membervariablen benutzt werden.

    mfg Martin



  • mgaeckler schrieb:

    sefie schrieb:

    Fehler: » A.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: static float A::aVar" (?aVar@A@@2MA)". «

    Ich hoffe meine Frage klingt jetzt nicht zu überheblich, aber es interessiert mich einfach:

    Was ist an der Fehlermeldung so schwer zu verstehen?

    Es sagt ganz klar, was der Linker vermisst hat. Und wenn ich zwar die Deklaration sehe und ich mir nicht sicher bin, ob das reicht, schaue ich doch als erstes in mein C++-Lehrbuch, um zu schauen, wie statische Membervariablen benutzt werden.

    mfg Martin

    Das klingt nur begrenzt überheblich, da ich nicht besonders darauf hingewiesen habe, dass ich an sich eigentlich nicht wirklich c++ kann, sondern mit Hilfe eines "Lehrbuches" (oben genanntes "Thinking in c++") versuche für ein einzelnes Projekt so schnell wie möglich zu Ergebnissen zu kommen. Da der Betreuer der Arbeit auch darauf hinwies, dass Schönheit des Codes oder Performanz keine Bewertungskriterien für mich sind, sondern allein die Funktionalität und das theoretische Gerüst auf dem das Programm aufbaut habe ich jetzt nicht Wochen darauf verwendet, Hello Worlds und so etwas zu programmieren. Das bedeutet natürlich auch, dass ich niemanden habe, der mir direkt beibringen kann, wie c++ im Gegensatz zu Java und AS3 funzt, sondern mir meine Infos zusammensammeln darf.



  • Tachyon schrieb:

    Nichtstatische Member können sowohl auf statische als auch auf nicht-statische Member zufreifen.

    😃

    Ich fass mal nochmal zusammen, was wir eigentlich sagen wollten. 😃

    1. Statische Methoden können nur auf statische Attribute zugreifen.
    2. Nicht-statische Methoden können sowohl auf nicht-statische als auch auf statische Attribute zugreifen.

    sodele :p



  • mgaeckler schrieb:

    sefie schrieb:

    Fehler: » A.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: static float A::aVar" (?aVar@A@@2MA)". «

    Ich hoffe meine Frage klingt jetzt nicht zu überheblich, aber es interessiert mich einfach:

    Was ist an der Fehlermeldung so schwer zu verstehen?

    Es sagt ganz klar, was der Linker vermisst hat. Und wenn ich zwar die Deklaration sehe und ich mir nicht sicher bin, ob das reicht, schaue ich doch als erstes in mein C++-Lehrbuch, um zu schauen, wie statische Membervariablen benutzt werden.

    mfg Martin

    Was ist so schwer daran zu verstehen, dass Anfänger nicht gleich jede Fehlermeldung verstehen? Erzähl mir nicht, du hast angefangen zu programmieren und gleich jede Meldung, die der Compiler ausgespuckt hat, hundertprozentig verstanden...


Log in to reply