为什么调用C++中的这个虚函数会导致基类中的“缺失符号”错误?
我有一个虚拟类,其定义如下:为什么调用C++中的这个虚函数会导致基类中的“缺失符号”错误?,c++,templates,linker-errors,C++,Templates,Linker Errors,我有一个虚拟类,其定义如下: template<typename TId, typename TValue> class Resource { private: /// Next item in the chain unique_ptr<Resource<TId, TValue>> data; protected: /// The id this value TId id;
template<typename TId, typename TValue>
class Resource {
private:
/// Next item in the chain
unique_ptr<Resource<TId, TValue>> data;
protected:
/// The id this value
TId id;
/// The value on this value
TValue value;
public:
/// Create a new instance and assign the values to it
Resource(TId id, TValue value) {
this->id = id;
this->value = value;
}
/// Destructor
virtual ~Resource() {
}
/// Safely clone a new instance of this
virtual Resource<TId, TValue> *Clone();
... other stuff removed for brevity ...
/// Create a new resource chain with a custom filter
Option<Resource<TId, TValue>*> Filter(std::function< bool(Resource<TId, TValue>*) > filter) {
auto iter = this->Iter<Resource<TId, TValue>>(filter);
if (iter.Any()) {
auto index = 0;
auto root = (*iter.First())->Clone();
iter.Each([&] (Resource<TId, TValue>* r) {
if (index != 0) {
root->Push(r->Clone());
}
++index;
});
return Some<Resource<TId, TValue>*>(root);
}
return None<Resource<TId, TValue>*>();
}
};
然而,在编译时,我得到:
[ 88%] Building CXX object CMakeFiles/test-resource.dir/tests/test-resource.cpp.o
Linking CXX executable tests/test-resource
Undefined symbols for architecture x86_64:
"npp::Resource<RType, int>::Clone()", referenced from:
vtable for npp::Resource<RType, int> in test-resource.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [tests/test-resource] Error 1
make[1]: *** [CMakeFiles/test-resource.dir/all] Error 2
编译器是铿锵的,平台是OSX
发生什么事了
为什么调用函数时,派生类中的实现不会自动解析
是因为这是一个模板化方法吗
完整的代码可以在以下要点中找到,以供参考:如果不想实现基类的虚拟成员函数,则必须将其声明为纯虚拟:
// vvv-- here
virtual Resource<TId, TValue> *Clone() = 0;
否则,链接器将搜索您声明但在为基类生成虚拟函数表时未实现的函数,您可以在收到的错误消息中看到这一点
请注意,在其中声明纯虚拟成员函数将使类抽象。如果不想实现基类的虚拟成员函数,则必须将其声明为纯虚拟:
// vvv-- here
virtual Resource<TId, TValue> *Clone() = 0;
否则,链接器将搜索您声明但在为基类生成虚拟函数表时未实现的函数,您可以在收到的错误消息中看到这一点
请注意,在其中声明纯虚拟成员函数将使类抽象。以后,请在其中声明一个纯虚拟成员函数。一些我们可以直接粘贴和尝试的最少代码的东西。虚拟类到底是什么?将来,请创建一个虚拟类。一些我们可以直接粘贴和尝试的最少代码的东西。虚拟类到底是什么?
// vvv-- here
virtual Resource<TId, TValue> *Clone() = 0;