2014-10-10 132 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(),因为它不是纯虚拟的,所以你需要为它创建一个默认实现,这样当派生类没有为它创建一个实现时,就会使用基类中的实现。