2016-03-07 28 views
-1

我試圖寫一個基類,它包含幾個非常類似的虛擬方法,我希望使用模板來減少重複的虛擬方法:C++:模板有不同的返回類型

class CPU { 
    template<typename T> 
    T getRegister(unsigned int which) { 
     /** Returns value of specified register. 
     */ 
     return *(T*)this->getRegisters()[which].data; 
    }; 
    virtual int16_t getRegister(unsigned int which); 
    virtual uint16_t getRegister(unsigned int which); 
    virtual int32_t getRegister(unsigned int which); 
    virtual uint32_t getRegister(unsigned int which); 
    //etc... 
}; 

class Z80: public CPU: { ... }; 
Z80 myCPU; 
printf("Register 0 = 0x%04X\n", myCPU.getRegister<uint16_t>(0)); 

目標適用於單個CPU可以定義自己的getRegister()或使用CPU基類中定義的那個。

我不確定究竟是什麼正確的語法是使這項工作,如果它甚至可能?

是不同於大部分的答案我發現

要點:

  • 類本身不是一個模板
  • 的方法是虛擬
+0

你不能有(虛擬)重載,唯一不同的是返回類型。 – Jarod42

+0

用不同的名字怎麼樣?我可以提供getRegister ()或getRegister_uint32_t()而不重複執行嗎? – Rena

回答

1

我去尋找一個重複,但無法找到一個......我確定有一個,但是我輸入的內容都不會找到一個好的。

C++不允許具有不同返回類型的具有相同簽名[1]的兩個函數。編譯器需要直接從函數簽名中知道返回類型。

有幾種不同的方法來解決該具體情況下:

1)聲明不同的功能:

virtual int16_t getRegisterS16(unsigned int which); 
virtual uint16_t getRegisterU16(unsigned int which); 
virtual int32_t getRegisterS32(unsigned int which); 
virtual uint32_t getRegisterU32(unsigned int which); 

2)使用一種間接型:

virtual void getRegister(unsigned int which, int16_t &value); 
virtual void getRegisterU16(unsigned int which, uint16_t &value); 
... 

3)使用一個具有CPU固定寄存器大小的模板:

template<typename T> 
class CPU { 
    T getRegister(unsigned int which) { 
     ... 
    } 
}; 

我也會在這裏做一個說明,對於99%的CPU操作,有符號和無符號數學是相同的。它只是比較不同的操作[至少在合理的現代CPU中,你可以期望在現代的x86或ARM處理器上執行數學計算,而不是在簡單的數學步驟中單獨模擬每一位]

[1]簽名是名稱,參數類型和成員函數,無論是否爲const - 我認爲可能有一兩個更多的事情,但這些是主要的。

+0

我可以做#1而不重複函數的實際代碼嗎?即使用模板創建具有不同名稱的幾個類似方法? – Rena

+0

不確定。實際上他們之間會有什麼不同 - 你總是可以做一個基本的函數來獲取寄存器號碼'which'和'static_cast'到正確的類型。在編寫CPU模擬器的整個方案中,這只是一小段代碼。 –

+0

(我的簡單CPU模擬器大概有2300行,但包括一個簡單的彙編程序以及模擬器本身 - 但它僅適用於單個CPU類型,我自己發明,並且非常易於模擬) –