2012-04-04 4 views
2

Ich habe alle Klassendefinitionen in einer Header-Datei: ModelModule.h. Ich habe für diese Datei des Beispielcode zur Verfügung gestellt unten, wo ich die Erklärung von 2 Klassen gegeben habe und ihre Mitgliedsfunktionen:Eclipse C++ - Projekt erstellt nicht: Konstruktor Destruktor Problem

#pragma once 

#if !defined(MODELMODULE_H) 
#define MODELMODULE_H 


//Required header files 

class CModelModule; 
class COrdProbitMM; 

class CModelModule 
// virtual base class for all types of modeling modules 
{ 
    friend class CSimCoordinator; 
    friend class CHouseholdCoordinator; 
    friend class CGenericHousehold; 

    public: 
     CModelModule(void); 
     ~CModelModule(void); 

    protected: 
     std::string   m_Label;   
     std::vector<int>  m_AvailEndAttr;  
     void GetVarValues(std::vector<int>&, std::vector<double> &); 


    public: 


     virtual void Configure(void){}; 
     virtual void loadXmlString(xmlNodePtr pXmlNode, xmlDocPtr pXmlDoc, xmlChar * con); 
     virtual void SaveXml(std::ofstream& fout){}; 

     double mrand(void); 
     double UniformRand();   // returns a U[0,1] random number 
     double StdNormalRand();  // returns a N(0,1) random number 
}; 

class COrdProbitMM : public CModelModule 
// Class represent the ordered-probit models 
{ 
    friend class CSimCoordinator; 
    friend class CHouseholdCoordinator; 
    friend class CMMRunner; 

    public: 
     COrdProbitMM(CSimCoordinator& simcord, std::string& sLabel); 
     COrdProbitMM(CSimCoordinator& simcord, std::string& sLabel, int nAlts); 
     ~COrdProbitMM(void); 

    private: 

     int    m_Max_nAlts;  
     std::vector<double>  m_Thresholds; 

    public: 
     void Configure(void); 
     void copyConfigure(COrdProbitMM* that); 

     int Run(CHouseholdObject*); 
     int Run(CPersonObject*); 


     void loadXmlString(xmlNodePtr pConfNode, xmlDocPtr pXmlDoc, xmlChar* con); 

    private: 
     int  Run(void); 
}; 

Nun wird die Funktionsdefinitionen haben in einer CPP-Datei gegeben worden: ModelModule.cpp. Hinweis: Die Header-Datei wurde eingefügt.

#include "ModelModule.h" 
//Other header files 

//Code for all the other functions defined here 

//Given below are the code for how the constructors and destructors are defined 

COrdProbitMM::~COrdProbitMM(void) 
{ 
} 

CModelModule::CModelModule(void) 
{ 
} 

CModelModule::~CModelModule(void) 
{ 
} 

Ich habe den Code von jedem syntaktischen Fehler befreit. Wenn ich jedoch den Code erstelle, bekomme ich den Fehler make: * [ProjectName] Error1. Auf Inspektion der Konsole finde ich die folgenden Wesen angezeigt:

Building target: Project Name 
Invoking: GCC C++ Linker 
g++ -o "XYZ" ./src/XYZ.o ./src/DataCache\ -\ Copy.o ./src/DataCache.o ./src/DataCoordinator.o ./src/DataObject.o ./src/HouseholdCoordinator.o ./src/ 
LinearEquation.o ./src/MMRunner.o ./src/MainFrm.o ./src/ModelModule.o ./src/SimCoordinator.o ./src/main.o -lxml2 -lsqlite3 

./src/ModelModule.o: In function `CModelModule::CModelModule()': 
ModelModule.cpp:(.text._ZN12CModelModuleC2Ev[CModelModule::CModelModule()]+0xd): undefined reference to `vtable for CModelModule' 
./src/ModelModule.o: In function `CModelModule::~CModelModule()': 
ModelModule.cpp:(.text._ZN12CModelModuleD2Ev[CModelModule::~CModelModule()]+0xd): undefined reference to `vtable for CModelModule' 

./src/ModelModule.o:(.rodata._ZTI12COrdProbitMM[typeinfo for COrdProbitMM]+0x8): undefined reference to `typeinfo for CModelModule' 

collect2: ld returned 1 exit status 
make: *** [Project Name] Error 1 

**** Build Finished **** 

ich dieses Forum für die VTable Fehler überprüft und es wurde erwähnt, dass das Problem ist, wenn wir einen Konstruktor/Destruktor deklarieren, aber es nie definieren. Aber das scheint in diesem Fall kein Problem zu sein, wie es in ModelModule.cpp explizit gemacht wurde. Es scheint etwas sehr Grundlegendes hier zu sein, das meine Aufmerksamkeit auf sich zieht.

  • Was fehlt mir?
  • Können Sie mir sagen, was mit der virtuellen Funktion ist und wie es den Fehler verursacht hat?
  • Ist es irgendwie mit dem Konstruktor und Destruktor verbunden?
+1

Haben Sie Definitionen für ** Alle ** angegeben, die Sie als 'virtuell' deklariert haben? Der Fehler ist typisch, wo Sie die Definition für eine 'virtuelle' Methode vermissen.Standard schreibt vor, dass alle Methoden außer rein' virtuell' eine Definition haben sollen. –

+0

virtuelles void Konfigurieren (void) {}; virtueller void loadXmlString (xmlNodePtr pXmlNode, xmlDocPtr pXmlDoc, xmlChar * con); virtuelles void SaveXml (std :: ofstream & fout) {}; - Ich habe diese drei definiert .... – sriramn

+0

Wie wäre es mit 'CModelModule :: loadXmlString'? –

Antwort

3

Root Cause:
Sie erhalten den Fehler, da die C++ Standard-Mandate, die Alle virtuellen Methoden einer Klasse mit Ausnahme der rein virtuellen Methoden Must haben eine Definition [# 1].

Lösung:
Entweder bieten Definitionen auf alle Ihre virtual Methoden oder sie reine virtual machen.

Erläuterung:
Die von gcc erzeugt Fehler in solchen Szenarien ist bestenfalls falsch führt. Hier ist ein sample program, die das Problem zeigt, Sie haben:

class MyClass 
{ 
    public: 
    virtual void doSomething() { } 
    virtual void doSomethingMore(); 
}; 

int main() 
{ 
    MyClass obj; 
    obj.doSomething(); 
    obj.doSomethingMore(); 
    return 0; 
} 

Kompilation Info:

/home/4VqWl0/ccMjLi2V.o: In Funktion main':
prog.cpp:(.text+0x19): undefined reference to
VTable für MyClass .
prog.cpp:(.text+0x1e): undefined reference to
MyClass :: doSomethingMore()‘
collect2: ld returned 1 exit status

Wie Sie sehen GCC in der Berichterstattung Fehler für diese Art von Problem ist berüchtigt.

Ist es irgendwie mit dem Konstruktor und dem Destruktor verbunden?

Die gcc faq doccuments es auch:

Die ISO C++ Norm legt, dass alle virtuellen Methoden einer Klasse, die nicht rein virtuell sind, müssen definiert werden, aber keine Diagnose für Verletzungen erfordern dieser Regel [class.virtual]/8. Basierend auf dieser Annahme gibt GCC nur die implizit definierten Konstruktoren, den Zuweisungsoperator, den Destruktor und die virtuelle Tabelle einer Klasse in der Übersetzungseinheit aus, die ihre erste derartige nicht-inline-Methode definiert.

Daher, wenn Sie diese bestimmte Methode nicht definieren, kann der Linker über das Fehlen von Definitionen für scheinbar nicht verwandte Symbole beschweren. Um diese Fehlermeldung zu verbessern, ist es leider möglicherweise erforderlich, den Linker zu ändern, was nicht immer möglich ist.

Die Lösung besteht darin, sicherzustellen, dass alle virtuellen Methoden, die nicht rein sind, definiert sind. Beachten Sie, dass ein Destruktor auch dann definiert sein muss, wenn er als rein virtuell deklariert ist [class.dtor]/7.

Good Read:

What does it mean that the "virtual table" is an unresolved external?


[# 1]C++ 03 Standard: 10.3 Virtuelle Funktionen [class.virtual]

Eine virtuelle Funktion dez in einer Klasse gebildet werden, werden definiert oder in dieser Klasse für rein erklärt (10.4) oder beides; aber keine Diagnose ist erforderlich (3.2).

+1

Das machte das Problem Kristall und legte es in die richtige Perspektive !! Vielen Dank! – sriramn

Verwandte Themen