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的转换。
然而编译连接的时候,却报错了
报错的位置在ClassB的test2()方法,这一行:
显然,
但编译器没有找到在ClassC中定义的getKeyFromObject的实现,为什么呢?
编译器在遇到纯虚拟函数时,会从父类开始一层层向下寻找,如果在子类中找到该函数,但还是被定义为纯虚函数,则会继续向子类的子类中寻找。如果子类中没有定义该函数,就中断查找过程。即使子类的子类中有实现该纯虚拟函数,也找不到。
上面的ClassB(也就是第二层)中没有定义这个纯虚拟函数。所以即使ClassC(第三层)中实现了该函数,编译也会报错。
知道原因,就好解决了:
在ClassB中再定义一次该函数,同样申明成纯虚函数,并且在第二层调用的时候,不能指定调用父类的函数
只需要修改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;//再次定义为纯虚函数 }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- 设计模式之行为型模式 - 调用行为的传递问题
- [div+css]晒晒最新制作专题推广页模板
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- 2008大学生入党申请书 模板
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- IMAIL多语言模板两套Outlook&Gmail模板下载
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例