Fehler: undefined reference to `vtable for CObject'
-
Hallo!
Ich hab da ein kleines Problem beim erstellen eines Projekts.
Da wären ein paar Klassen: Die Grundklasse CObject:class CObject { protected: GtkWidget* pWidget; public: CObject() { } ~CObject() { } GtkWidget* GetWidget(); virtual void Create()=0; // erstellt Widget void Show(); // Zeigt Widget an };
Und eine davon abgeleitete Klasse CWindow:
class CWindow : public CObject { private: string szTitle; // Name des Fensters gint iWidth; // Breite gint iHeight; // Höhe d. Fensters public: CWindow(); ~CWindow(); string GetTitle(); // Titel des Fensters gint GetWidth(); // Breite gint GetHeight(); // Höhe void SetTitle(string str); // Titel des Fensters setzen void SetDimensions(gint w, gint h); // Setzt Höhe und Breite void Create(); // Erstellt das Fenster };
Die Hauptdatei sieht so aus:
#include <stdlib.h> #include <gtk/gtk.h> #include "window.h" int main(int argc, char* argv[]) { gtk_init(&argc,&argv); CWindow hWindow; hWindow.SetTitle("Hello World!"); hWindow.Create(); hWindow.Show(); gtk_main(); return 0; }
Wenn ich nun meine Makefile ausführe, die so aussieht...
# VARIABLEN ===========================================// CC = g++ FLAGS = `pkg-config --cflags --libs gtk+-2.0` OBJ = player.o window.o object.o # REGELN UND ABHÄNGIGKEITEN ===========================// # alle Objektedateien zum Programm linken all: $(OBJ) $(CC) -g -o player $(OBJ) $(FLAGS) # Alle O-Datei hängen von entsprechenden cpp-Dateien ab! %.o: %.cpp $(CC) $(FLAGS) -c $<
...dann bekomme ich folgende Fehlermeldung:
g++ -g -o player player.o window.o object.o `pkg-config --cflags --libs gtk+-2.0`
window.o(.gnu.linkonce.t._ZN7CObjectC2Ev+0x8): In functionCObject::CObject[not-in-charge]()': : undefined reference to
vtable for CObject'
window.o(.gnu.linkonce.t._ZN7CObjectD2Ev+0x8): In functionCObject::~CObject [not-in-charge]()': : undefined reference to
vtable for CObject'
window.o(.gnu.linkonce.r._ZTI7CWindow+0x8): undefined reference to `typeinfo for CObject'
collect2: ld returned 1 exit status
make: *** [all] Fehler 1Ich weiß echt nicht wo der Fehler liegt! Vielleicht ist es zu lange her, dass ich C++ programmiert habe und deswegen finde ich den Fehler nicht. Kann jemand von euch mir sagen wo der Fehler liegt?
-
Kann es sein, dass CObject Create() nicht implementiert ist?
-
mach mal den destruktor von CObject virtual...
auf bald
oenone
-
Ja, virtual void CObject::Create() ist nicht implementiert. Es ist aber auch eine virtuelle Funktion. Leider habe ich vergessen zu schreiben: Create()=0;
Wie auch immer, ich habe den Code unten um diese Änderung aktualisiert.Die Fehlermeldung hat sich jedoch nicht wesentlich verändert:
g++ -g -o player player.o window.o object.o `pkg-config --cflags --libs gtk+-2.0`
window.o(.text+0xe): In functionCWindow::CWindow[not-in-charge]()': : undefined reference to
CObject::CObject[not-in-charge]()'
window.o(.text+0x87): In functionCWindow::CWindow[not-in-charge]()': : undefined reference to
CObject::~CObject [not-in-charge]()'
window.o(.text+0xb0): In functionCWindow::CWindow[in-charge]()': : undefined reference to
CObject::CObject[not-in-charge]()'
window.o(.text+0x129): In functionCWindow::CWindow[in-charge]()': : undefined reference to
CObject::~CObject [not-in-charge]()'
window.o(.text+0x175): In functionCWindow::~CWindow [not-in-charge]()': : undefined reference to
CObject::~CObject [not-in-charge]()'
window.o(.text+0x191): In functionCWindow::~CWindow [not-in-charge]()': : undefined reference to
CObject::~CObject [not-in-charge]()'
window.o(.text+0x1cf): In functionCWindow::~CWindow [in-charge]()': : undefined reference to
CObject::~CObject [not-in-charge]()'
window.o(.text+0x1eb): In functionCWindow::~CWindow [in-charge]()': : undefined reference to
CObject::~CObject [not-in-charge]()'
window.o(.gnu.linkonce.r._ZTI7CWindow+0x8): undefined reference to `typeinfo for CObject'
collect2: ld returned 1 exit status
make: *** [all] Fehler 1Auch ein virtueller Destruktur hatte keine Besserung zur Folge (eigentlich gar keinen Effekt).
-
Sind alle Methoden von CObject implementiert, die nicht abstrakt sind?
-
object.cpp:
#include "object.h" void CObject::Show() { gtk_widget_show(pWidget); } GtkWidget* CObject::GetWidget() { return pWidget; }
Also, ja.
-
Kannst du den Code vielleicht zusammengepackt auf eine Seite stellen?
-
Kommt sofort!:
player.cpp (Hauptdatei):
#include <stdlib.h> #include <gtk/gtk.h> #include "window.h" int main(int argc, char* argv[]) { gtk_init(&argc,&argv); CWindow hWindow; hWindow.SetTitle("Hello World!"); hWindow.Create(); hWindow.Show(); gtk_main(); return 0; }
window.h
#ifndef _WINDOW_H_ #define _WINDOW_H_ /* CWindow, Standart-Fensterklasse @2004 - Mathias Kahl LastChange: 23. Dezember 2004 */ #include <stdlib.h> #include <string> #include <gtk/gtk.h> #include "object.h" using namespace std; class CWindow : public CObject { private: string szTitle; // Name des Fensters gint iWidth; // Breite gint iHeight; // Höhe d. Fensters public: CWindow(); ~CWindow(); string GetTitle(); // Titel des Fensters gint GetWidth(); // Breite gint GetHeight(); // Höhe void SetTitle(string str); // Titel des Fensters setzen void SetDimensions(gint w, gint h); // Setzt Höhe und Breite void Create(); // Erstellt das Fenster, basierend auf private }; #endif
window.cpp
#include "window.h" // CONSTRUCTOR & DESTRUCTOR ----------------------// CWindow::CWindow() { szTitle = "CWindow"; iWidth = iHeight = 200; } CWindow::~CWindow() { } // GETTER --------------------// string CWindow::GetTitle() { return szTitle; } gint CWindow::GetWidth() { return iWidth; } gint CWindow::GetHeight() { return iHeight; } // SETTER -------------------// void CWindow::SetTitle(string str) { pWidget = NULL; szTitle = str; gtk_window_set_title(GTK_WINDOW(pWidget), str.c_str() ); } void CWindow::SetDimensions(gint w, gint h) { iWidth = w; iHeight = h; } // ---------------------------------// void CWindow::Create() { if(pWidget != NULL) return; pWidget = gtk_button_new_with_label(szTitle.c_str() ); }
object.h
#ifndef _OBJECT_H_ #define _OBJECT_H_ /* Grundklasse für GTK-Widgets. Fasst grundlegende Eigenschaften zusammen. @2004 - Mathias Kahl Last Change: 23. Dezember 2004 */ #include <stdlib.h> #include <gtk/gtk.h> class CObject { protected: GtkWidget* pWidget; public: CObject() { } virtual ~CObject() { } GtkWidget* GetWidget(); virtual void Create()=0; // erstellt Widget void Show(); // Zeigt Widget an }; #endif
object.cpp
#include "object.h" void CObject::Show() { gtk_widget_show(pWidget); } GtkWidget* CObject::GetWidget() { return pWidget; }
Die Makefile findest du in meinem ersten Posting.
-
1. Das ganze kompiliert und linkt ohne Probleme. Hast du mal alles clean gemacht und neu kompiliert?
2. #include <cstdio> ist besser
3. #ifndef WINDOW_H_ is besser als #ifndef _WINDOW_H_, da Namen, die mit einem Unterstrich anfangen für dich tabu sind.
4. Gtk is eine C library. Deshalb:extern "C" { #include <gtk/gtk.h> }
5. Das folgende Makefile gefaellt mir besser:
# VARIABLEN ===========================================// CC = g++ CFLAGS = `pkg-config --cflags gtk+-2.0` LDFLAGS = `pkg-config --libs gtk+-2.0` OBJ = player.o window.o object.o # REGELN UND ABHÄNGIGKEITEN ===========================// # alle Objektedateien zum Programm linken all: $(OBJ) $(CC) -g -o player $(OBJ) $(LDFLAGS) # Alle O-Datei hängen von entsprechenden cpp-Dateien ab! %.o: %.cpp $(CC) $(CFLAGS) -c $<
-
Hey, vielen Dank!
Es scheint wirklich an der Makefile gelegen zu haben.
Zu einem habe ich "vergessen" nach dem Kompilieren sauber zu machen, und zum anderen war die Makefile falsch. Nachdem ich mit meiner alten Makefile nochmals kompilierte waren klarere Fehlermeldungen das Ergebnis, dann mit den Änderungen an der Makefile hats geklappt. Ich bin dir wirklich sehr dankbar!!Also nochmal vielen Dank an alle und speziell an Ponto!