Fehler mit undefined reference to.. Was ist da falsch???



  • Hey,
    ich habe seit langem nicht mehr in C++ programmiert und bin jetzt dabei es wieder zu lernen. Jetzt implementiere ich gerade ein paar design Patterns. Ich verwende Qt.

    Wo ist das Problem bei meiner Implementierung? Es treten folgende fehler bei zwei Klassen auf:

    ...\stockgrabber.cpp:1: Fehler: undefined reference to `StockGrabber::notifyObserve()'

    ...\stockobserver.cpp:7: Fehler: undefined reference to `observer::~observer()'

    ...\stockobserver.cpp:17: Fehler: undefined reference to `observer::~observer()'

    hier der Code:

    Stockgraber:

    #ifndef STOCKGRABBER_H
    #define STOCKGRABBER_H
    
    #include "subject.h"
    #include <vector>
    #include <iostream>
    #include <algorithm>
    
    class StockGrabber : public Subject
    {
    
    private:
        std::vector<observer*> observers;
        double ibmPrice;
        double aaplPrice;
        double googPrice;
    public:
        StockGrabber();
        virtual ~StockGrabber();
    
    
        // Subject interface
    public:
        void registerObserver(observer &o);
        void unregisterObserver(observer &o);
        void notifyObserver();
        void setibmPrice(double newPrice);
        void setaaplPrice(double newPrice);
        void setgoogPrice(double newPrice);
    
        // Subject interface
    public:
        void notifyObserve();
    };
    
    #endif // STOCKGRABBER_H
    
    #include "stockgrabber.h"
    
    StockGrabber::StockGrabber()
    {
    
    }
    
    StockGrabber::~StockGrabber()
    {
    
    }
    
    
    void StockGrabber::registerObserver(observer &o)
    {
        observers.push_back(&o);
    }
    
    void StockGrabber::unregisterObserver(observer &o)
    {
        auto itr=std::find(observers.begin(),observers.end(), &o);
    
        int index = std::distance(observers.begin(),itr);
         std::cout<<"Observer" << index << "deleted"<<std::endl;
    
        if(itr!=observers.end())
        {
          observers.erase(itr);
        }
    }
    
    void StockGrabber::notifyObserver()
    {
        std::for_each(observers.begin(),observers.end(),[&](observer* o){o->update(ibmPrice,aaplPrice,googPrice);});
    }
    
    void StockGrabber::setibmPrice(double newPrice)
    {
        this->ibmPrice=newPrice;
    }
    
    void StockGrabber::setaaplPrice(double newPrice)
    {
        this->aaplPrice=newPrice;
    }
    
    void StockGrabber::setgoogPrice(double newPrice)
    {
        this->googPrice=newPrice;
    }
    

    StockObserver:

    #ifndef STOCKOBSERVER_H
    #define STOCKOBSERVER_H
    
    #include <iostream>
    #include "Observer.h"
    #include "subject.h"
    
    
    
    class StockObserver : public observer
    {
    
    private:
        double ibmPrice;
        double aaplPrice;
        double googPrice;
    
        static int observerIDTracker;
        int observerID;
        Subject* stockGrabber;
    public:
        StockObserver(Subject &newStockGrabber);
        ~StockObserver();
    
        // observer interface
    public:
        void update(double &ibmPrice, double &aaplPrice, double &googPrice);
        void printThePrices();
    };
    
    #endif // STOCKOBSERVER_H
    
    #include "stockobserver.h"
    
    
    
    int StockObserver::observerIDTracker=0;
    
    StockObserver::StockObserver(Subject &newStockGrabber)
    {
        this->stockGrabber=&newStockGrabber;
        this->observerID = ++StockObserver::observerIDTracker;
    
        std::cout<<"New Observer "<<this->observerID<<std::endl;
    
        newStockGrabber.registerObserver(*this);
    }
    
    StockObserver::~StockObserver()
    {
    
    }
    
    void StockObserver::update(double &ibmPrice, double &aaplPrice, double &googPrice)
    {
        this->ibmPrice=ibmPrice;
        this->aaplPrice=aaplPrice;
        this->googPrice=googPrice;
    
    
    }
    
                   void StockObserver::printThePrices()
    {
                   std::cout<<"observerID: "<<this->observerID<<std::endl
                           <<"IBM: "<<this->ibmPrice<<std::endl
                           <<"AAPL: "<<this->aaplPrice<<std::endl
                           <<"GOOG: "<<this->googPrice<<std::endl;
    }
    

    Ich danke euch 😃



  • @Shadow99 sagte in Fehler mit undefined reference to.. Was ist da falsch???:

    notifyObserve

    Such einfach mal danach in dem Code, den du gepostet hast. Wo findest du das alles und wo nicht?



  • @Mechanics

    Super 😃 Ein Fehler weniger. Hatte vergessen den Schreibfehler in der abstrakten klasse zu korrigieren!



  • Und wegen den anderen, wie schaut dein "observer" aus?



  • @Mechanics

    Der zweite fehler war, dass ich bei einer abstrakten observerklasse den construktor als virtual definiert hatte. Wenn ich den constructor weg lasse, dann bekomme ich die Warnung: "subject.h:6:7: warning: 'Observer' has virtual functions but non-virtual destructor". Es funktioniert dann. Ich würde die Warnung aber trotzdem weg haben. Ich will eigentlich nur ein interface in C++ erstellen, so wie das in Java oder c# der fall ist.



  • @Shadow99 sagte in Fehler mit undefined reference to.. Was ist da falsch???:

    virtual definiert hatte

    Vermutlich hattest du ihn nur deklariert, nicht definiert.
    Geht am einfachsten mit =default, z.B.

    virtual ~observer() = default;



  • p.s. Grundsätzlich kommt "undefined reference" meist daher, dass eine Funktion deklariert, aber nicht definiert wurde.



  • @Mechanics

    Wenn ich Observer definiere, dann kommt wieder der selbe Fehler:

    Hier mein Observerinterface:

    #ifndef OBSERVER_H
    #define OBSERVER_H
    
    class Observer
    {
    virtual ~Observer()=default;
    
        public:
            virtual void update(double &ibmPrice, double &aaplPrice, double &googPrice)=0;
    };
    
    #endif // OBSERVER_H
    


  • @Shadow99

    dann kommt wieder der selbe Fehler:

    Das bezweifle ich.

    Warum ist der Destruktor privat?



  • Kommt mir auch komisch vor. Wie sieht dein restlicher Code aus?
    Außerdem sieht deine API schon etwas verdächtig aus. Du verwaltest eine Liste von Zeigern, reingegeben wird aber eine Referenz (nicht mal const). Das sieht nicht geraden robust aus 😉


Anmelden zum Antworten