[英]Why does calling this virtual function in C++ result in a 'missing symbol' error from the base class?
我有一個虛擬類,其定義如下:
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>*>();
}
};
我已經在測試中輕松實現了這一點,如下所示:
enum RType {
ThingOne = 1,
ThingTwo = 2
};
class RValue : public Resource<RType, i32> {
public:
RValue(int value) : Resource(ThingOne, value) {
}
~RValue() {
}
Resource<RType, i32>* Clone() {
return new RValue(this->value);
}
};
注意 注意克隆的用法:
root->Push(r->Clone());
但是,在編譯時我得到:
[ 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
編譯器是clang,平台是OSX。
這是怎么回事?
為什么在調用函數時不能自動解析派生類中的實現?
是否因為這是模板化方法?
完整的代碼可以在本要點中找到,以供參考: https : //gist.github.com/shadowmint/d49650668e9a74c324a1
如果您不想實現基類的虛成員函數,則必須將其聲明為純虛的:
// vvv-- here
virtual Resource<TId, TValue> *Clone() = 0;
否則,鏈接器將在為基類生成虛擬函數表時搜索您聲明但未實現的函數(您可以在收到的錯誤消息中看到該函數)。
請注意,在其中聲明純虛擬成員函數將使類抽象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.