1. 程式人生 > >c++ template 多層繼承下找不到純虛擬函式實現 報錯:undefined reference to "xxx"

c++ template 多層繼承下找不到純虛擬函式實現 報錯:undefined reference to "xxx"

如下程式碼中,定義了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;//再次定義為純虛擬函式
}

相關推薦

c++ template 繼承虛擬函式實現 :undefined reference to "xxx"

如下程式碼中,定義了3個類,ClassA,ClassB,ClassC,依次為被繼承關係,ClassA,ClassB是模板類, 在ClassA中定義了一個純虛擬函式getKeyFromObject,實現將從V中獲取K的功能: getKeyFromObject函

C++在繼承中呼叫虛擬函式

在一個類中的虛擬函式說明,只對派生類中重定義的函式有影響,對它的基類中的函式不起作用。 例: #include <iostream> usingnamespacestd; class A { public:     void show()  

myeclipse到Deployment Assembly ,

今天tomcat載入maven專案遇到錯誤: java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener 在網上查到解決方法: 出自:http://www.c

kbengine前期設定相關mysql8.0 'caching_sha2_password' cannot be loaded: 到指定的模組解決

TelnetServer server is running on port 32000 dbmgr-1: [ERROR] DBInterfaceMysql::attach: mysql_errno=2059, mysql_error=Authenticatio

MyEclipse工具使用-到Maven Dependencies專案

轉自:http://www.xuebuyuan.com/2225268.html myeclipse不是很穩定,總是會出各種各樣的漏子,我一直都這樣覺得,但是又覺得比eclipse功能多多了。 這次出現的問題是maven專案被IDE識別了,但是沒有出現maven de

dubbo到dubbo.xsd,Multiple annotations found at this line:

參考http://blog.csdn.net/zbw18297786698/article/details/54582071 報錯: Multipleannotations found at this line: – cvc-complex-type.2.4.c: Th

Linux C/C++ 開發遇到 undefined reference to xxx

環境 CentOS 7.3 CodeBlocks 16.01 gcc 4.9.4 wxGTK 3.0.2 非常簡單的應用。例如: test.h #ifndef TEST_H_INCLUDED #define TEST_H_INCLUDED void test(); #end

g++編譯連結c語言檔案undefined reference ” 的處理

用QT寫一介面程式,其中用到另一同事寫的一個小功能,他是用c語言寫的,於是把他的程式碼標頭檔案和原始檔都copy過來了,加入工程中,結果連結的時候就總報錯 undefined reference 某個函式。再三確認了makefile檔案和原始碼,表示沒問題,後來想到或許是g+

C++】——型()再探虛表&不同繼承帶有虛擬函式的物件模型

一、虛擬函式 1、概念:簡單地說,那些被virtual關鍵字修飾的成員函式,就是虛擬函式。虛擬函式的作用,用專業術語來解釋就是實現多型。 2、程式碼示例: class Base { public: virtual void TestFunc1() {

綜合運用: C++11 線程生產者消費者模型詳解(轉)

並發 rep 生產 我會 交流 模型 操作 const ref 生產者消費者問題是多線程並發中一個非常經典的問題,相信學過操作系統課程的同學都清楚這個問題的根源。本文將就四種情況分析並介紹生產者和消費者問題,它們分別是:單生產者-單消費者模型,單生產者-多消費者模型,多生產

模板類繼承到父類函數的問題

argument 有關 過程 類繼承 找不到 his cout this 添加 錯誤示例: 1 template<class T> class List 2 { 3 public: 4 void next(T*){

Centos到eth0設備的解決方法

運行 ip地址 scripts drive lan get 自動生成 情況 引導 問題描述: ifconfig命令無法找到eth0設備,且/etc/sysconfig/network-scripts/中只有ifcfg-lo文件,而沒有ifcfg-eth0。 臨時

【js】前臺調試,在瀏覽器調試環境到js怎麽辦?

alt 所有 body 圖片 ron 點擊 nbsp 分享 方法 針對這次 整個項目單頁面的情況下,所有點擊出現的新頁面都是追加在母頁面的情況下,很多時候不像原本的情況,可以直接在瀏覽器的調試環境下找到想要調試的js代碼 這種情況下,怎麽能找到子頁面的js代碼,調試呢

CentOS添加新網卡network-scripts目錄到網卡配置文件

CentOS7 網卡 問題描述: 使用VMware Workstation虛擬機,安裝好CentOS7虛擬機後(原本只有一張網卡ifcfg-ens33),重新添加了一個新的網卡。 進入CentOS7系統後,使用ip addr 查看狀態如下: 發現ens

交叉編譯環境在root用戶到arm-linux-gcc問題:

root GC 路徑 bashrc 問題 編譯 用戶 環境變量 重新 原因是:環境變量(交叉編譯路徑)可能是在普通用戶下添加的,所以在root用戶下創建的文件使用arm-linux-gcc編譯的時候,找不到arm-linux-gcc。 解決辦法:找個終端:sudo -s  

Linux到so文件的解決辦法

ldconfig -name desktop 末尾 添加 文件搜索 libjson 出現 技術 http://www.cnblogs.com/xudong-bupt/p/3698294.html 如果使用自己手動生成的動態鏈接庫.so文件,但是這個.so文件,沒有加入庫文

解決eclipse中web專案部署至Tomcat在Tomcat安裝目錄到專案問題

必須知道的一點 Eclipse的web工程至Tomcat預設的部署目錄是在工程空間下,而myeclipse預設是在Tomcat安裝目錄下的(在webapps和work目錄下都會有你部署的專案) 那麼如何將部署目錄改為Tomcat安裝目錄 1.在Eclipse中新增Tomcat伺服

在子類中新增新功能,繼承

class Animal: def eat(self): print("-----吃-----") def drink(self): print("-----喝-----") class Dog(Animal): def bark(self): print("-----汪汪

ubuntu到sys/time.h標頭檔案(沒有/usr/include/sys目錄)

今天編譯一個工程,編譯器報錯sys/time.h標頭檔案找不到~ 開啟目錄/usr/include看了一下,發現下面根本沒有sys目錄 實際上不是沒有sys目錄,只是系統給換路徑了 32位系統:/usr/incude/i386-linux-gnu/sys 64位系統:/usr/inc

linux到新增的動態庫

可以用ldd檢視你可執行檔案的依賴庫,例如要檢視test這個應用的依賴庫 ldd test 1. 使用export匯出LD_LIBRARY_PATH加入你so的路徑。 在命令列中輸入: export LD_LIBRARY_PATH=$LD_LIBRARY_PAT