2012-06-12 31 views
1

我有下面的代碼:Undifined參考`虛表在和Base2

// IBase.h 
#include <iostream> 

class IBase{ 
    public: 
      virtual string getId(); 
}; 

// IBase.cpp 
#include "IBase.h" 
string IBase::getId(){}; 

// Base.h 
#include <iostream> 
#include <string> 
#include "IBase.h" 

using namespace std; 
class Base : public IBase{ 
    protected: 
      string id; 
    public: 
      Base(string _id); 
      string getId(); 
}; 

// Base.cpp 
#include "Base.h" 

Base::Base(string _id){ 
    id = _id; 
} 
string Base::getId(){ 
    return id; 
} 

// Base2.h 
#include <iostream> 
#include <string> 
#include "Base.h" 
using namespace std; 

class Base2 : public Base{ 
    public: 
      Base2(string _id); 
      string getId(); 
}; 

// Base2.cpp 
#include "Base2.h" 
Base2::Base2(string _id) : Base(_id){}; 

,我得到未定義參考`VTABLE在和Base2當我編譯項目!這是我想念的東西嗎?

+0

順便說後無需分號,推杆'{};'在這些情況下是'pedantic'下的警告。這也許值得投入頭球衛士。 – chris

+1

爲了響應chirs的評論,指定沒有實現的「abstract」函數的正確方法是使用語法'virtual void blah(int i)= 0;'。例如,您的IBase類應該看起來像http://ideone.com/VCO1D。不需要IBase.cpp。 – Lalaland

+0

如果我刪除'IBase.cpp',我有一個編譯錯誤! –

回答

1

對vtable的未定義引用通常表示第一個虛擬函數(通常存儲vtable的地方)未鏈接。

由於沒有提供Base2::getId的定義(第一個虛函數),因此沒有vtable被鏈接。

要麼爲Base2::getId添加定義,要麼刪除類定義中的函數聲明。

+0

謝謝,所以如果在'IBase'類中,我有一個'virtual'函數,每個繼承類(兒子,孫子......)都必須定義'IBase'的'virtual'函數,對吧? –

+1

@Kingfisher不,不要留下任何聲明,它會自動繼承超類。 – Lalaland

1

函數聲明需要一個定義。否則,聲明會簡單地禁止函數定義(可能從基地繼承)。您有以下選擇:

  • 取出string getId();Base2類聲明或
  • 通過一個usingdeclaration自己定義的函數,或
  • 導入從合適的基類特定的定義,如using Base::getId;

還要注意的是以下幾點:

string IBase::getId(){}; 
  • 需要定義return語句(和返回一個對象可轉換爲string
  • 定義