undefined reference auf einen virtuellen Destruktor



  • Hallo Leute,

    ich habe ein Problem bei dem Zusammenspiel einer abstrakten Schnittstellenklasse:

    Die Klasse Communication soll als Schnittstelle fungieren:

    class Communication
    {
    public:
        virtual ~Communication();
    
        virtual bool Open();
        virtual void Close();
        virtual bool isInterfaceConnected();
        virtual bool isSnifferConnected();
        virtual void SendData(unsigned char*, int);
        virtual QList<unsigned char> GetData();
    };
    

    Die Klasse FTDI soll die Klasse Communication implementieren:

    #include "Communication.h"
    #include "ftd2xx.h"
    #include "global.h"
    
    class FTDI : public Communication
    {
    public:
    	FTDI();
    	~FTDI();	
    	/*
    	 * Methode zum Öffnen der Schnittstelle
    	 */
    	bool Open();
    
    	/*
    	 * Methode zum Schließen der Schnittstelle
    	 */
    	void Close();
    
    	/*
    	 * Methode zum Überprüfen der Verbindung zum Interface (FTDI, Ethernet, o.ä.)
    	 */
    	bool isInterfaceConnected();
    
    	/*
    	 * Methode zum Überprüfen der verbindung zum Hitachi
    	 */
    	bool isSnifferConnected();
    
    	/*
    	 * Methode zum Senden von Daten an die Hardware
    	 */
    	void SendData(unsigned char*, int);
    
    	/*
    	 * Methode zum Empfangen von Daten von der Hardware
    	 */
    	QList<unsigned char> GetData();
    
    private:
    	FT_STATUS		ftStatus;
    	FT_HANDLE		ftHandle;
    	unsigned long 	numDevices;
    	unsigned char 	RxBuffer[25000];
    	QList<unsigned char>	newTelegram;
    	unsigned char i_aufrufe;
    };
    

    Alle Methoden der Klasse FTDI wurden implementiert.
    Der Compiler listet weder Fehler noch Warnings. Aber der Linker:

    ./debug/FTDI.o: In function ZN4FTDIC2Ev': C:/Qt/Projekte/fmbMonitor/FTDI.cpp:25: undefined reference toCommunication::~Communication()'
    ./debug/FTDI.o: In function ZN4FTDIC1Ev': C:/Qt/Projekte/fmbMonitor/FTDI.cpp:25: undefined reference toCommunication::~Communication()'
    ./debug/FTDI.o: In function ZN4FTDID2Ev': C:/Qt/Projekte/fmbMonitor/FTDI.cpp:29: undefined reference toCommunication::~Communication()'
    C:/Qt/Projekte/fmbMonitor/FTDI.cpp:29: undefined reference to Communication::~Communication()' ./debug/FTDI.o: In functionZN4FTDID1Ev':
    C:/Qt/Projekte/fmbMonitor/FTDI.cpp:29: undefined reference to Communication::~Communication()' ./debug/FTDI.o:C:/Qt/Projekte/fmbMonitor/FTDI.cpp:29: more undefined references toCommunication::~Communication()' follow
    ./debug/FTDI.o: In function Z16q\_atomic\_set_ptrPVvPv': C:/Qt/Projekte/fmbMonitor/../../4.3.3/include/QtCore/../../src/corelib/thread/qatomic.h:(.text$_ZN13CommunicationC2Ev[Communication::Communication()]+0x8): undefined reference tovtable for Communication'

    Kann mir das jemand erklären, was der Linker von dem virtuellen Destruktor und dem nicht existierendem Konstruktor will??

    Mit freundlichen Grüßen

    Christian



  • Du fällst auf einen C++ Sonderfall rein.

    Ein virtueller Destruktor braucht dennoch eine Implementierung, und sei es im einfachsten Fall wie folgt:

    virtual ~Klasse() {};

    Dies gilt auch dann, wenn der Destruktur rein virtuell deklariert ist (dann halt noch mit =0).

    cu André
    Nachtrag: JEDE rein virtuelle Funktion (ohne Implementierung) immer mit =0 deklarieren [ virtual int foo() = 0; ].



  • Soll die pure abstract sein? Dann fehlt da noch was:

    class Communication
    {
    public:
        virtual ~Communication(){}
    
        virtual bool Open()=0;
        virtual void Close()=0;
        virtual bool isInterfaceConnected()=0;
        virtual bool isSnifferConnected()=0;
        virtual void SendData(unsigned char*, int)=0;
        virtual QList<unsigned char> GetData()=0;
    };
    

    MfG Kimmi



  • Dass Dein Destruktor virtuell ist ändert nichts daran dass Du ihn implementieren musst. Du gibst ja nicht explizit an, dass es sich um eine abstrakte, d.h. nicht implementierte Funktion handelt. (Aber Achtung: Der Destuktor ist ein Sonderfall, der selbst dann, wenn er abstrakt ist, eine Implementierung benötigt, einfach weil der Destruktor der abgeleiteten Klasse ihn aufruft.)

    Die fehlende vtable dürfte demselben Problem entstammen, da der g++ (dessen Meldungen ich hier zu erkennen glaube) die vtable immer an den Ort der Implementierung der ersten virtuellen Funktion der Klasse legt.



  • Wo implementiere ich denn den virtuellen Destruktor? Wenn ich die leere Implementierung

    Communication::~Communication(){};

    mit an das Ende der Header-Datei hänge, in der die Klasse deklariert wurde, dann werde ich nur so mit Fehlern überhäuft.

    Muss ich für die eine Zeile eine extra cpp-Datei spendieren?



  • Entweder Du schiebst sie in eine eigene cpp-Datei
    Oder Du definierst "inline Communication::~Communication() {}" im Header
    Oder Du definierst direkt in der Klasse "virtual ~Communication() {}" (wie von kimmi vorgeschlagen)



  • sorry, hatte das mit dem {} von kimmi überlesen.

    Nun Funktioniert scheinbar alles.

    Danke!


Anmelden zum Antworten