undefined reference problem



  • @Swordfish sagte in undefined reference problem:

    @Swordfish sagte in undefined reference problem:

    Wie sieht denn nun Dein kompletter Code aus? Wie wird Compiler und Linker aufgerufen? Was steht (alles!) im Ausgabefenster von Code::Blocks?

    ?

    @mmmmmmmm sagte in undefined reference problem:

    OK, dieser vector spiegelt das Board bei einem Pokerspiel wieder. Auf diesen vector soll innerhalb der gesamten Klasse zugegriffen werden können. Ich hoffe das beantwortet die Frage.

    Ich habe noch keine Partie Poker gespielt bei der bei Spielbeginn eine -1 auf dem Tisch rumlag. 🤔

    Ok, das ist halt mein Status für ein leeres Board. Ich komme von Java und da kann mein Array nicht leer sein. Ich vermute in C++ geht das mit einem Pointer auf einen vector.



  • @mmmmmmmm sagte in undefined reference problem:

    Ok, das ist halt mein Status für ein leeres Board.

    std::vector::size()

    @mmmmmmmm sagte in undefined reference problem:

    Ich komme von Java und da kann mein Array nicht leer sein.

    Ein std::vector ist ja auch kein Array. Ein Array kann in C++ auch nicht "leer" sein.

    @mmmmmmmm sagte in undefined reference problem:

    Ich komme von Java und da kann mein Array nicht leer sein. Ich vermute in C++ geht das mit einem Pointer auf einen vector.

    Hör auf mit Pointern. Deshalb sollst Du ja den kompletten Code zeigen, weil Du sicher noch anderen Unfug gebaut hast. Man lernt aus seinen Fehlern. Nur wenn man die Fehler selbst nicht erkennt ist auch die Chance vertan etwas zu lernen.



  • Ok, aktueller Code:

    pokerface.cpp

    #include <pokermind.h>
    #include <iostream>
    
    int main()
    {
      pokermind poa;
    
      poa.setboardadd(1);
    }
    

    pokermind.cpp

    #include <iostream>
    #include <vector>
    
    class pokermind
    {
      std::vector<char> vucboard = {1, -1};
    
      pokermind()
      {
      }
    
      char pokermind::boardcheck(char card)
      {
        for (unsigned char uca = 0; uca < vucboard.size(); uca++)
        {
          if (vucboard[uca] == card)
          {
            return uca;
          }
        }
    
        return -1;
      }
      void pokermind::setboardadd(char card)
      {
        if (card != -1)
        {
          if (vucboard[0] == -1)
          {
            vucboard[0] = card;
          }
          else if ((boardcheck(card) == -1) & (vucboard.size() < 5))
          {
            vucboard.push_back(card);
          }
        }
      }
    
      void pokermind::setboardremove(char card)
      {
        if (card != -1)
        {
          int uca = boardcheck(card);
    
          if (uca != -1)
          {
            if (vucboard[0] == -1)
            {
              vucboard[0] == card;
            }
            else
            {
              vucboard.erase(vucboard.begin() + uca - 1);
            }
          }
        }
      }
    };
    

    pokermind.h:

    #ifndef POKERMIND_H_INCLUDED
    #define POKERMIND_H_INCLUDED
    #include <vector>
    
    class pokermind
    {
      public:
        pokermind();
        void setboardadd(char card); // fügt, falls möglich, dem board card zu.
        void setboardremove(char card); // entfernt, falls möglich, card vom board
      private:
        std::vector<char> vucboard;
    
        char boardcheck(char card); // checked ob card bereits im board vorhanden ist. gibt -1 oder den index zurück.
    };
    
    #endif // POKERMIND_H_INCLUDED
    

    Meine aktuelle Fehlermeldung:
    ||=== Build: Debug in poker (compiler: GNU GCC Compiler) ===|
    C:\c++\poker\pokermind.cpp|13|error: extra qualification 'pokermind::' on member 'boardcheck' [-fpermissive]|
    C:\c++\poker\pokermind.cpp|26|error: extra qualification 'pokermind::' on member 'setboardadd' [-fpermissive]|
    C:\c++\poker\pokermind.cpp|41|error: extra qualification 'pokermind::' on member 'setboardremove' [-fpermissive]|
    C:\c++\poker\pokermind.cpp||In constructor 'pokermind::pokermind()':|
    C:\c++\poker\pokermind.cpp|10|error: 'initialize' was not declared in this scope|
    C:\c++\poker\pokermind.cpp||In member function 'void pokermind::setboardremove(char)':|
    C:\c++\poker\pokermind.cpp|51|warning: value computed is not used [-Wunused-value]|
    ||=== Build failed: 4 error(s), 1 warning(s) (0 minute(s), 0 second(s)) ===|

    Eine schnelle Googlesuche sagt mir das ich die pokermind:: wieder entfernen soll. Also auf gut Deutsch ich habe keine Ahnung was ich tun soll.



  • Mit

    class pokermind
    {
        // ...
    };
    

    definierst Du die Klasse zweimal, einmal in pokermind.h und einmal in pokermind.cpp. Man inkludiert die Definition der Klasse (bei Dir in pokermind.h) in der Implementierung (bei Dir pokermind.cpp). Schau Dir noch mal mein Beispiel weiter oben genau an.

    @mmmmmmmm sagte in undefined reference problem:

      char pokermind::boardcheck(char card)
      {
        for (unsigned char uca = 0; uca < vucboard.size(); uca++)
        {
          if (vucboard[uca] == card)
          {
            return uca;
          }
        }
    
        return -1;
      }
    

    Das Ding soll nichts anderes tun als eine Karte finden? std::find()

    @mmmmmmmm sagte in undefined reference problem:

      void pokermind::setboardadd(char card)
      {
        if (card != -1)
        {
          if (vucboard[0] == -1)
          {
            vucboard[0] = card;
          }
          else if ((boardcheck(card) == -1) & (vucboard.size() < 5))
          {
            vucboard.push_back(card);
          }
        }
      }
    

    Wie schon angedeutet. vucboard nicht initialisieren und

    bool pokermind::setboardadd(char card)
    {
      if (card == -1 || vucboard.size() == 5)
          return false;
    
      vucboard.push_back(card);
      return true;
    }
    

    @mmmmmmmm sagte in undefined reference problem:

      void pokermind::setboardremove(char card)
      {
        if (card != -1)
        {
          int uca = boardcheck(card);
    
          if (uca != -1)
          {
            if (vucboard[0] == -1)
            {
              vucboard[0] == card;
            }
            else
            {
              vucboard.erase(vucboard.begin() + uca - 1);
            }
          }
        }
      }
    

    ~>

    void pokermind::setboardremove(char card)
    {
        if (card == -1)
            return;  // early-exit. Nicht alles andere nochmal in Klammern zwingen.
    
        if (vucboard.size())
            vucboard.erase(std::remove(vucboard.begin(), vucboard.end(), card), vucboard.end());
        else
            vucboard.push_back(card);
    }
    

    Soll nur das erste gefundene Element getilgt werden:

    void pokermind::setboardremove(char card)
    {
        if (card == -1)
            return;
    
        if (vucboard.size())
            vucboard.erase(std::find(vucboard.begin(), vucboard.end(), card));
        else
            vucboard.push_back(card);
    }
    


  • Dieser Beitrag wurde gelöscht!


  • @Swordfish

    Vielen Dank (nochmals) für deine Hilfe. Die doppelte Klassendefinition war das Problem. Inzwischen läuft mein Programm. Es terminiert aber jedesmal wenn ich auf meinen vector zugreife. Ich lese mir erstmal durch was du zuletzt geschrieben hast.



  • Was hast Du denn mit

    @mmmmmmmm sagte in undefined reference problem:

    std::vector<char> vucboard = {1, -1};
    

    aus pokermind.cpp gemacht? Steht das jetzt wo anders, diese Initialisierung?



  • @Swordfish

    #include <iostream>
    #include <pokermind.h>
    #include <vector>
    
      std::vector<char> vucboard = {1, -1};
    
      pokermind::pokermind()
      {
    
      }
    
      char pokermind::boardcheck(char card)
      {
        for (unsigned char uca = 0; uca < vucboard.size(); uca++)
        {
          if (vucboard[uca] == card)
          {
            return uca;
          }
        }
    
        return -1;
      }
    
      void pokermind::setboardadd(char card)
      {
        if (card != -1)
        {
                std::cout << vucboard[0];
          if (vucboard[0] == -1)
          {
            vucboard[0] = card;
          }
          else if ((boardcheck(card) == -1) & (vucboard.size() < 5))
          {
            vucboard.push_back(card);
          }
        }
      }
    
      void pokermind::setboardremove(char card)
      {
        if (card != -1)
        {
          int uca = boardcheck(card);
    
          if (uca != -1)
          {
            if (vucboard[0] == -1)
            {
              vucboard[0] == card;
            }
            else
            {
              vucboard.erase(vucboard.begin() + uca - 1);
            }
          }
        }
      }
    

    Ich hatte einfach die Klassendefinition gelöscht und dafür die Header Datei included. Wieso meine vector Initialisierung nicht akzeptiert wird ist mir auch nicht klar.



  • @mmmmmmmm sagte in undefined reference problem:

    std::vector<char> vucboard = {1, -1};
    

    in deiner pokermind.cpp hat nichts mit pokermind::vucboard zu tun. Ersatzlos streichen, dafür in pokermind.h:

    // ...
    
    class pokermind
    {
        // ...
    
    private:
        std::vector<char> vucboard = { 1, -1 };
    
        // ...
    };
    
    // ...
    

    @mmmmmmmm sagte in undefined reference problem:

    #include <pokermind.h>
    

    Gewöhn' Dir bitte die spitzen Klammern für Header die es in Deinem Projekt gibt ab. Mit spitzen Klammern wird zuerst in den Standard-Include-Directories gesucht und dann erst im Arbeitsverzeichnis. Wenn Du mal einen Header hast der zufällig den selben Namen hat wie einer in den Standard-Include-Directories funktioniert das nicht mehr.

    ~>

    #include "pokermind.h"
    


  • // pseudogelöschter Doppelpost.



  • @Swordfish

    Wie immer vielen Dank. Jetzt läuft es problemlos. Ich schaue mir dann mal deine Codeoptimierungen. Ja, da gibt es noch sehr viel zu lernen für mich.



  • @Swordfish sagte in undefined reference problem:

    definierst Du die Klasse zweimal, einmal in pokermind.h und einmal in pokermind.cpp. Man inkludiert die Definition der Klasse (bei Dir in pokermind.h) in der Implementierung (bei Dir pokermind.cpp).

    Da stimmen das Wording nicht. Die Deklaration wird inkludiert und die Definition der Member Functions erfolgt in den .cpp Dateien - Ausnahme Templates.



  • @john-0 Du setzt dich verdammt oft ins Fettnäpfchen sobald du anfängst klugzuscheißen. Guckst du class. Du wording du.

    class foo;  // declaration
    
    class foo {};  // definition
    


  • @Swordfish sagte in undefined reference problem:

    @john-0 Du setzt dich verdammt oft ins Fettnäpfchen sobald du anfängst klugzuscheißen.

    Jetzt, hast Du es richtig verwendet, und vorher nicht.



  • @john-0 Leiß die beiden Sätze die du zitiert hast nochmal. und dann nochmal. und dann nochmal. ...



  • @Swordfish
    Wie schön, dass Du Deinen Fehler gelöscht hast, und nun weiter meinst schlechtes Benehmen an den Tag legen zu müssen.



  • @john-0 ich habe seit deinem ersten Post in diesem Thread garnichts gelöscht. Ich habe mich nur in meinem vorigen Post korrigiert. "Ließ den Satz den" ~> "Ließ die beiden Sätze die".

    ps: Ach so, in meiner ersten Antwort auf deinen ersten Post habe ich "Guckst du" hinzugefügt und einen Zeilenumbruch entfernt.

    @john-0 sagte in undefined reference problem:

    Jetzt, hast Du es richtig verwendet, und vorher nicht.

    Wo was wann? In dem von dir zitiertem? Ne. Und auch daran habe ich nichts geändert. Die beiden Sätze stehen genau so wie von dir zitiert in jeder Revision des betreffenden Posts. Von Anfang an.



  • @Swordfish sagte in undefined reference problem:

    @john-0 ich habe seit deinem ersten Post in diesem Thread garnichts gelöscht.

    Du hast Dein Posting mit dem Fehler gelöscht!

    Fehler passieren jedem und immer wieder, aber Deine Reaktion auf einen neutralen Hinweis ist absolut daneben. Wenn man so sich benimmt, braucht man sich nicht zu wundern, wenn immer weniger Nutzern im Forum sind. Ist es so schwer einen simplen Flüchtigkeitsfehler zuzugeben und sich zu korrigieren?

    @Swordfish sagte in

    … Man inkludiert die Definition der Klasse (bei Dir in pokermind.h) in der Implementierung (bei Dir pokermind.cpp). …

    Das casus delicti um das es geht.



  • @john-0 sagte in undefined reference problem:

    Du hast Dein Posting mit dem Fehler gelöscht!

    In diesem gesamten Thread gibt es nur einen einzigen gelöschten Post von mir, in dem es um spitze Klammern versus Anführungszeichen bei #include ging. Ich habe ihn gelöscht, weil ich kein Fan von doppelposts bin und habe den Inhalt 1:1 in den vorhergehenden Post eingefügt. Aber nur für dich, stelle ich auch diesen Post wieder her, wenn es denn sein muss.

    @john-0 sagte in undefined reference problem:

    Das casus delicti um das es geht.

    Ja. Was soll daran falsch sein?



  • @Swordfish sagte in undefined reference problem:

    Ja. Was soll daran falsch sein?

    Die Definition einer member function ist deren Implementation. D.h. es hätte bei Dir heißen müssen, man inkludiert in der .cpp Datei die Deklaration der Klasse die Definition der Klasse mit den Deklarationen der member functions und definiert die member functions ebendort in der .cpp Datei. Templates sind die Ausnahme, da dort Deklaration und Definition sowohl von Klassen wie auch der member functions im Header erfolgen.


Anmelden zum Antworten