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 functionZN4FTDIC1Ev': C:/Qt/Projekte/fmbMonitor/FTDI.cpp:25: undefined reference toCommunication::~Communication()'
./debug/FTDI.o: In functionZN4FTDID2Ev': C:/Qt/Projekte/fmbMonitor/FTDI.cpp:29: undefined reference toCommunication::~Communication()'
C:/Qt/Projekte/fmbMonitor/FTDI.cpp:29: undefined reference toCommunication::~Communication()' ./debug/FTDI.o: In functionZN4FTDID1Ev':
C:/Qt/Projekte/fmbMonitor/FTDI.cpp:29: undefined reference toCommunication::~Communication()' ./debug/FTDI.o:C:/Qt/Projekte/fmbMonitor/FTDI.cpp:29: more undefined references toCommunication::~Communication()' follow
./debug/FTDI.o: In functionZ16q\_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!