2014-10-10 172 views
2

下面是我在編譯時發現了錯誤:未定義符號

Undefined symbols for architecture x86_64: 
    "typeinfo for BaseClass", referenced from: 
     typeinfo for DerivedOne in base-49c1cd.o 
     typeinfo for DerivedTwo in base-49c1cd.o 
    "vtable for BaseClass", referenced from: 
     BaseClass::BaseClass() in base-49c1cd.o 
    NOTE: a missing vtable usually means the first non-inline virtual member function has no definition. 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 
make: *** [test] Error 1 

這裏的base.h

class BaseClass { 
public: 
    // an enum 
protected: 
    float variable 
public: 
    float getVariable(); 
    void printBase(); 
    virtual BaseClass* clone(); 
    virtual float calculate(bool _one, bool _two) = 0; 
}; 

class DerivedOne: public BaseClass { 
public: 
    DerivedOne(float _variable); 
    BaseClass* clone(); 
    float calculate(bool _one, bool _two); 
}; 

class DerivedTwo: public BaseClass { 
public: 
    DerivedTwo(float _variable); 
    BaseClass* clone(); 
    float calculate(bool _one, bool _two); 
}; 

base.cpp

#include "base.h" 

float BaseClass::getVariable() { 
    return variable; 
} 

void BaseClass::printBase() { 
    return; // not implemented yet 
} 

DerivedOne::DerivedOne(float _variable) { 
    variable = _variable; 
} 

BaseClass* DerivedOne::clone() { 
    DerivedOne* tmp = new DerivedOne(variable); 
    return tmp; 
} 

float DerivedOne::calculate(bool _one, bool _one) { 
    float val = //some calculation; 
    return val; 
} 

DerivedTwo::DerivedTwo(float _variable) { 
    variable = _variable; 
} 

BaseClass* DerivedTwo::clone() { 
    DerivedTwo* tmp = new DerivedTwo(variable); 
    return tmp; 
} 

float DerivedTwo::calculate(bool _one, bool _two) { 
    float val = //some calculation; 
    return val; 
} 

我改變了變量的名字,所以我可能會犯一個錯字。

我認爲我的問題源於我對構造函數和抽象類缺乏瞭解。任何人都可以爲我清理一些東西嗎?

回答

5

您沒有提供執行BaseClass:clone方法。要麼是純虛擬的,即=0要麼提供實現。

錯誤消息基本上告訴原委:

注:缺少虛函數表通常意味着第一非內嵌虛擬成員函數沒有定義。

您提供了聲明,但沒有提供定義。

+0

謝謝,我想我沒有真正理解虛擬和嚴格虛擬(我知道這有一個名稱)之間的區別。我以爲我不需要在BaseClass中聲明'clone()',因爲它是在派生類中實現的。謝謝! – n0pe 2014-10-10 23:02:35

+0

此外,它是「純粹的虛擬」,而不是抽象的。當一個類有(至少有一個)純虛函數時,該類是抽象的。除了使用'= 0;'來聲明一個純虛擬成員嗎? – Deduplicator 2014-10-10 23:03:35

+1

@Deduplicator,謝謝,似乎c#成了我的主要語言... – 2014-10-10 23:04:51

0

請嘗試添加在你下面的 'base.cpp'

BaseClass::BaseClass() 
{ 
    //do something (if there's any) 
} 
BaseClass::~BaseClass() 
{ 
    //do something (if there's any) 
} 
BaseClass::clone() 
{ 
    //do something (if there's any) 
} 

:-)

鏈接正在尋找您的BaseClass的定義。 如果您不像上面的示例那樣將代碼寫入代碼中,則會產生未定義的參考鏈接器錯誤。 而clone(),因爲它不是純虛擬的,所以你需要爲它創建一個默認實現,這樣當派生類沒有爲它創建一個實現時,就會使用基類中的實現。