2012-04-04 28 views
2

すべてのクラス定義は、ヘッダーファイルModelModule.hにあります。Eclipse C++プロジェクトがビルドされていません:コンストラクタデストラクタ問題

#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); 
}; 

次に関数定義は、.cppファイルに付与されている:ModelModule.cpp私は2つのクラスとそのメンバ関数の宣言を与えている場合、以下に、そのファイルのためのサンプルコードを提供しています。注:ヘッダーファイルが含まれています

#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) 
{ 
} 

構文エラーのコードを削除しました。しかし、コードをビルドするときにエラーが発生します。* [ProjectName] Error1。私は、次が表示されて見つけるコンソール検査で:

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 **** 

を私はvtableのエラーのためにこのフォーラムをチェックアウトし、それは私たちがコンストラクタ/デストラクタを宣言し、それを定義することはありませんときに問題があることを述べました。しかし、ModelModule.cppで明示的に行われているので、このケースでは問題はないようです。私の注意を奪っている、ここで起こっている非常に基本的なことがあるようです。

  • 私が紛失していることは何ですか?
  • バーチャルファンクションの機能とそのエラーの原因を教えてください。
  • 何とかコンストラクタとデストラクタにリンクしていますか?
+1

「すべて」の定義を提供しましたか?「仮想」と宣言したメソッドはありますか?このエラーは典型的なもので、 'virtual'メソッドの定義を見逃してしまいます。標準的な' virtual'以外のメソッドは全て定義されていなければなりません。 –

+0

virtual void Configure(void){}; 仮想void loadXmlString(xmlNodePtr pXmlNode、xmlDocPtr pXmlDoc、xmlChar * con); virtual void SaveXml(std :: ofstream&fout){}; - 私はこれら3つを定義しました.... – sriramn

+0

'CModelModule :: loadXmlString'はどうですか? –

答えて

3

根本原因:
C++標準は純粋仮想メソッドを除いて、クラスのすべて仮想メソッドは、 [#1]定義を持っていなければならないことを義務付けているのであなたは、エラーが発生します。

ソリューション:
すべてのvirtualメソッドに定義を提供したり、virtual彼らは純粋にするのどちらか。

説明:
このようなシナリオではgccによって生成されたエラーは、最高のミスリーディングです。

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

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

コンパイル情報:

/home/4VqWl0/ccMjLi2V.o:ここではあなたが持っている問題を示しsample programあるMyClassの.
prog.cpp:(.text+0x1e): undefined reference to
MyClassのために機能main':
prog.cpp:(.text+0x19): undefined reference to
のvtableで:: doSomethingMore()」
collect2は:あなたはGCCは、この問題の特定の種類のエラーを報告で悪名高いです見ての通りldは

1つの終了ステータスが返されました。

何とかコンストラクタとデストラクタにリンクしていますか?

gcc faq doccuments同様にそれ:

ISO C++標準では定義されなければならない、純粋仮想ではありませんが、クラスのすべての仮想メソッドは、違反のいずれかの診断を必要としないことを指定しますこの規則の[class.virtual]/8。この前提に基づいて、GCCは暗黙的に定義されたコンストラクタ、代入演算子、デストラクタ、およびその最初のそのような非インラインメソッドを定義する翻訳単位のクラスの仮想テーブルのみを出力します。

したがって、この特定のメソッドの定義に失敗した場合、リンカーは明らかに関係のないシンボルの定義が不十分であると不平を言う可能性があります。残念ながら、このエラーメッセージを改善するために、リンカーを変更する必要があり、これはいつでも実行できるとは限りません。

解決策は、純粋ではないすべての仮想メソッドが定義されていることを確認することです。デストラクタは、純粋な仮想[class.dtor]/7と宣言されていても定義する必要があることに注意してください。

グッド読む:

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


[#1]C++ 03標準:10.3仮想関数[class.virtual]

仮想関数decあるクラスで飼育されたものは、そのクラスで純粋に(10.4)定義されるか、あるいはその両方であると宣言されなければならない。診断は必要ありません(3.2)。

+1

それは問題のクリスタルを作り、適切な視点に入れました!ありがとうございました! – sriramn

関連する問題