未定义符号
问题描述:
下面是我在编译时发现了错误:未定义符号
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;
}
我改变了变量的名字,所以我可能会犯一个错字。
我认为我的问题源于我对构造函数和抽象类缺乏了解。任何人都可以为我清理一些东西吗?
答
您没有提供执行BaseClass:clone
方法。要么是纯虚拟的,即=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(),因为它不是纯虚拟的,所以你需要为它创建一个默认实现,这样当派生类没有为它创建一个实现时,就会使用基类中的实现。
谢谢,我想我没有真正理解虚拟和严格虚拟(我知道这有一个名称)之间的区别。我以为我不需要在BaseClass中声明'clone()',因为它是在派生类中实现的。谢谢! – n0pe 2014-10-10 23:02:35
此外,它是“纯粹的虚拟”,而不是抽象的。当一个类有(至少有一个)纯虚函数时,该类是抽象的。除了使用'= 0;'来声明一个纯虚拟成员吗? – Deduplicator 2014-10-10 23:03:35
@Deduplicator,谢谢,似乎c#成了我的主要语言... – 2014-10-10 23:04:51