您的位置:首页 > 编程语言 > C语言/C++

c++ template 多层继承下找不到纯虚拟函数实现 报错:undefined reference to "xxx"

2015-10-13 14:37 543 查看
如下代码中,定义了3个类,ClassA,ClassB,ClassC,依次为被继承关系,ClassA,ClassB是模板类,

在ClassA中定义了一个纯虚拟函数getKeyFromObject,实现将从V中获取K的功能:

getKeyFromObject函数在ClassA,ClassB中都有被调用,在ClassC中被实现。

按照我的思路,这样就成了。不论在Class,ClassB中,都会调用ClassC中的getKeyFromObject来实现V->K的转换。

//抽象类模板(第一层)
template<typename K, typename V>
class ClassA_Abstract {
public:
void test(V* obj){
getKeyFromObject(obj);//调用纯虚拟函数
}
protected:
/*纯虚拟函数,子类必须实现*/
virtual K* getKeyFromObject(V* obj)=0;
}

//抽象类模板(第二层)
template<typename K,typename V>
class ClassB_Abstract: public ClassA_Abstract <K, V> {
void test2(V* obj){
//在这里指定是调用父类的函数,要加上ClassA_Abstract <K, V>::
ClassA_Abstract <K, V>::getKeyFromObject(obj);//调用纯虚拟函数,
}
}

//普通实现类(第三层)
template<typename K>
class ClassC: public ClassB_Abstract<CKeyObj, CValueObj> {//CKeyObj, CValueObj为实际的对象
void test3(V* obj){
ClassA_Abstract <K, V>::getKeyFromObject(obj);
}
//实现纯虚拟函数
CKeyObj* getKeyFromObject(CValueObj*obj){
std::cout<<"ClassC::getKeyFromObject"<<endl;
return &obj->key;
}
}


然而编译连接的时候,却报错了

ClassB_Abstract.h:undefined reference to `ClassA_Abstract <CKeyObj, CValueObj>::getKeyFromObject(CValueObj*)'


报错的位置在ClassB的test2()方法,这一行:

ClassA_Abstract <K, V>::getKeyFromObject(obj);


显然,
ClassA_Abstract <CKeyObj, CValueObj>::getKeyFromObject(CValueObj*)
是个纯虚函数,

但编译器没有找到在ClassC中定义的getKeyFromObject的实现,为什么呢?

编译器在遇到纯虚拟函数时,会从父类开始一层层向下寻找,如果在子类中找到该函数,但还是被定义为纯虚函数,则会继续向子类的子类中寻找。如果子类中没有定义该函数,就中断查找过程。即使子类的子类中有实现该纯虚拟函数,也找不到。

上面的ClassB(也就是第二层)中没有定义这个纯虚拟函数。所以即使ClassC(第三层)中实现了该函数,编译也会报错。

知道原因,就好解决了:

在ClassB中再定义一次该函数,同样申明成纯虚函数,并且在第二层调用的时候,不能指定调用父类的函数

只需要修改ClassB(第二层)代码,修改后的代码是这样:

template<typename K,typename V>
class ClassB_Abstract: public ClassA_Abstract <K, V> {
void test2(V* obj){
getKeyFromObject(obj);
//去掉ClassA_Abstract <K, V>::
}
virtual K* getKeyFromObject(V* obj)=0;//再次定义为纯虚函数
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息