multiple definition meiner Klassenvariabel



  • Hi Leute!
    Ich schreibe gerade ein kleines Programm, um mich an c++ umzugewöhnen.
    Es geht um Klassenvariabeln, und ich finde meinen Fehler einfach nicht.
    Aber ich wette, ich seh nur mal wieder den Wald vor lauter Bäumen nicht, und der Fehler wäre eigentlich ganz einfach zu finden.
    Und zwar bricht der Compiler das kompilieren meines Projekts ab und spuckt diese Fehler meldung aus:
    " multiple definition of `Person::iAnzahl' "
    Anmerkung Person ist meine Klasse und iAnzahl meine Klassenvariabel (= Anzahl aller Instanzen von Person).

    Wie gesagt, fich finde meinen Fehler einfach nicht.
    Ich hab hier mal die Headerdatei, meine Klassendeklaration.
    Die ist eh das einzig wichtige:

    class Person{
      int iSize, iWeight, iAge, iIQ;
    
      unsigned ID;
      public:
      static unsigned iAnzahl;    
    
      public:
      Person() : iSize(175), iWeight(70), iAge(25), iIQ(100)){ID = iAnzahl++;}
      Person(int size, int weight, int age, int IQ) : iSize(size), iWeight(weight), iAge(age), iIQ(IQ){ID = iAnzahl++;}
      ~Person() {iAnzahl--;}
      Person(const Person& orig);
      void print();
      int getSize();
      int getWeight();
      int getAge();
      int getIQ();
      void increaseSize(int wert);
      unsigned getID(){return ID;};
      void setValues();
      Person& operator= (const Person& rS);
    };
    unsigned Person::iAnzahl = 0; //Definition außerhalb der Klasse ohne static
    

    Es wäre wirklich super, wenn mir da jemand helfen könnte. 🙂



  • Ganz einfach: Die Definition von iAnzahl darf nicht in der Headerdatei stehen. Man definiert keine Variablen in Headerdateien. Die Definition muss in eine .cpp-Datei.



  • Flabian schrieb:

    Hi Leute!
    Ich schreibe gerade ein kleines Programm, um mich an c++ umzugewöhnen.

    class Person{
      public:
      Person() : iSize(175), iWeight(70), iAge(25), iIQ(100)){ID = iAnzahl++;}
      Person(int size, int weight, int age, int IQ) : iSize(size), iWeight(weight), iAge(age), iIQ(IQ){ID = iAnzahl++;}
    };
    

    Wenn Du Dich schon an C++ gewöhnen willst, gewöhn Dir sowas gar nicht erst an. Sourcecode erbt nicht vom Telegramm, man muß nicht "pro Zeile" bezahlen. Viel wichtiger ist es, den Code übersichtlich zu gestallten.

    z.B. so (oder so ähnlich)

    class Person{
      public:
      Person() 
       : iSize(175)
       , iWeight(70)
       , iAge(25)
       , iIQ(100))
      {
         ID = iAnzahl++;
      }
    
      Person(int size, int weight, int age, int IQ) 
       : iSize(size)
       , iWeight(weight)
       , iAge(age)
       , iIQ(IQ)
      {
         ID = iAnzahl++;
      }
    };
    


  • Ah, super, ihr seid genial!

    Aus meinen Unterlagen, ging leider nicht hervor, dass die Definition innerhalb der .c Datei erfolgen muss.
    Da hätt ich ja noch ewig suchen können.

    Und schöner strukturiert habe ich sie jetzt auch.

    Vielen Dank für die super Hilfe! 🙂 👍 👍



  • hmm, sollte das nicht eine .cpp Datei sein?

    Und wuerde diese multiple Defintion nicht auch durch Include Guards verhindert? Resp wenn nicht wieso nicht? Und wenn nicht (und Fabian sie gesetzt hat) wieso hatte er dann keine multiple Definition der Klasse selbst?



  • Shinja schrieb:

    Und wuerde diese multiple Defintion nicht auch durch Include Guards verhindert?

    Nein.

    Resp wenn nicht wieso nicht?

    Weil Include-Guards nur verhindern dass der Präprozessor innerhalb einer Übersetzungseinheit einen Header mehrfach einbindet. Sie verhindern nicht, dass der Compiler innerhalb mehrerer Übersetzungseinheiten dieselbe Definition vorfindet.

    Und wenn nicht (und Fabian sie gesetzt hat) wieso hatte er dann keine multiple Definition der Klasse selbst?

    Weil die Klasse im Header üblicherweise nur deklariert wird. Und zwar dank Include-Guards in jeder ÜE genau einmal.



  • Shinja schrieb:

    Resp wenn nicht wieso nicht?

    Nein, wird sie nicht - Include-Guards verhindern nur das mehrfache Einbinden eines Headers in der selben Übersetzungseinheit. Der Linkerfehler tritt aber auf, weil der selbe Header in verschiedenen Übersetzungseinheiten eingebunden und übersetzt wurde.

    Und wenn nicht (und Fabian sie gesetzt hat) wieso hatte er dann keine multiple Definition der Klasse selbst?

    Klassendefinitionen werden etwas anders behandelt als Variablen-/Funktionsdefinitionen. Davon bleiben (vereinfacht ausgedrückt)für den Linker nur noch die Deklarationen der Memberfunktionen übrig - und mit mehrfachen Deklarationen hat er keine Probleme.



  • <OT> @CStoll: Wir sollten demnächst ausknobeln wer die Antwort gibt, sind ohnehin meist fast identisch 😃 </OT>



  • Vielen Dank Lord Jaxom und CStoll.

    btw: Bewundernswert wie jemand, der angeblich das Chaos bringt, so leicht Ordnung in nen Kopf reinbringen kann, hehe.



  • @LordJaxom: Hmm, darüber könnten wir mal nachdenken 😃

    Shinja schrieb:

    btw: Bewundernswert wie jemand, der angeblich das Chaos bringt, so leicht Ordnung in nen Kopf reinbringen kann, hehe.

    Ich hab' nie gesagt, daß ich für das Chaos verantwortlich bin 😃


Anmelden zum Antworten