2017-06-17 123 views
-3

考慮以下繼承和組合方案。具有非無效返回類型的虛函數

//例程序

#include <iostream> 
#include <valarray> 

using namespace std; 

class TapProcessing 
{ 
    public: 
      TapProcessing(){}; 
      virtual ~TapProcessing(){}; 

      virtual void getWeights(valarray<double> &weights) {}; 
      virtual void getPrecisionWeights (valarray<double> &precWeights) {}; 
      virtual const uint &getTapIndex(const uint index) const 
      { 
       valarray<uint> a; 
       a.resize(10); 
       return a[index]; 
      }; //const {return 0;}; 
      virtual const uint &getTapIndexLow(const uint index) const 
      { 
       valarray<uint> a; 
       a.resize(10); 
       return a[index]; 
      }; //const {return 0;};; 
      virtual const uint &getTapIndexHigh(const uint index) const 
      { 
       valarray<uint> a; 
       a.resize(10); 
       return a[index]; 
      }; //const {return 0;}; 

}; 

class StepPrecisionTapProcessing : public TapProcessing 
{ 
    public: 
     StepPrecisionTapProcessing() { _tapIndex.resize(10, 3); } 
     ~StepPrecisionTapProcessing() {}; 

     void getWeights(valarray<double> &weights) { return weights.resize(10);} 
     virtual const uint &getTapIndex(const uint index) const {return _tapIndex[index]; } 

    private: 
      valarray<uint> _tapIndex; 

}; 

class HighPrecisionTapProcessing : public TapProcessing 
{ 
    public: 
     HighPrecisionTapProcessing() 
     { 
      _tapIndexLow.resize(10, 4); 
      _tapIndexHigh.resize(10, 5); 
     } 
     ~HighPrecisionTapProcessing() {}; 

     void getPrecisionWeights (valarray<double> &precWeights) { return precWeights.resize(10); }; 
     virtual const uint &getTapIndexLow(const uint index) const {return _tapIndexLow[index]; } 
     virtual const uint &getTapIndeHigh(const uint index) const {return _tapIndexHigh[index]; } 

    private: 
      valarray<uint> _tapIndexLow; 
      valarray<uint> _tapIndexHigh; 

}; 

class Generator 
{ 
    public: 
      Generator(bool isPrecision) 
      { 
       if (isPrecision) {_tp = new HighPrecisionTapProcessing(); 
       } 
       else { _tp = new StepPrecisionTapProcessing(); } 
      } 

      ~Generator() { delete _tp; } 

      const uint &getTapIndex(const uint index) const {return _tp->getTapIndex(index); } 
      const uint &getTapIndexLow(const uint index) const {return _tp->getTapIndexLow(index); } 
      const uint &getTapIndexHigh(const uint index) const {return _tp->getTapIndexHigh(index); } 

    private: 
      TapProcessing *_tp; 
}; 



int main() 
{ 
    Generator *G = new Generator(true); 
    uint index = 5; 

    cout<<"High tap index is = "<<G->getTapIndexHigh(index)<<endl; 

    delete G; 
    return 0; 
} 

當運行主,我得到以下輸出,

高抽頭索引是= O

這裏如果getTapIndeHigh的聲明在派生類中重寫基類中的聲明,我們會看到輸出值爲5而不是0.爲什麼派生類實現不會覆蓋根據非虛方法的類方法?

+2

「是否可以使用非void返回類型的虛函數?」你試過了嗎? 「我可以給出一個虛擬的返回值,它將被派生類getter覆蓋嗎?」看來你錯過了一些對虛擬功能的基本理解。沒有「虛擬返回值」這樣的事情。它可以是被調用函數的返回值,也可以不是。你想要一個純虛函數嗎?這是一個在基類中沒有定義的虛函數。 https://en.wikipedia.org/wiki/Virtual_function#Abstract_classes_and_pure_virtual_functions – xaxxon

+2

編譯器無法確定「G」是「HighPrecisionTapProcessing」對象的實例。例如,如果'G'是'StepPrecisionTapProcessing'的一個實例,那麼你期望'G-> getTapIndexHigh(index)'返回什麼?由於沒有函數'StepPrecisionTapProcessing :: getTapIndexHigh(uint)'的聲明,因此運行時會調用基本函數'TapProcessing :: getTapIndexHigh(uint)',您沒有爲其提供返回值的定義。編譯器需要函數'virtual uint TapProcessing :: getTapIndexHigh(uint)'來返回'uint'值。 –

+0

你想要一個發生器實際包含特定類型的TapProcessing,但要有一個通用的接口和實現。我不確定你爲什麼要這樣做,但是如果這真的是你想要的,那麼我會讓你的TapProcesing基類在它的函數實現中拋出異常(如果編譯器仍然抱怨從未執行過的返回之前)你的派生類將被覆蓋。那樣的話,如果你在一個不被底層類型支持的Generator上調用了錯誤的函數,你將在運行時得到一個異常,使你不知道實際的底層類型。 – jschultz410

回答

0

問題是從這些行來了...

 virtual uint getTapIndex(uint index) {}; 
     virtual uint getTapIndexLow(uint index) {}; 
     virtual uint getTapIndexHigh(uint index) {}; 

他們描述它返回一個uint,提供了一個實現,但實際上沒有返回值的函數。

如果有一個明智的基礎實現,那麼它是很好的提供它。然而在這裏,你似乎想要一個pure virtual方法,使你的課程abstract。你想讓所有的派生類實現一個值。例如

 virtual uint getTapIndex(uint index) =0; // require derived classes to implement 
     virtual uint getTapIndexLow(uint index) { return 0 } // can be overridden, but defaults to returning zero. 
     virtual uint getTapIndexHigh(uint index) = 0; // require derived classes to implement. 
+0

所以問題是我不想在StepPrecisionTapProcessing中實現getTapIndexHigh和getTapIndexLow,並且在HighPrecisionTapProcessing中同樣是getTapIndex,因爲它們不屬於那裏。使它們變爲純虛擬將迫使我在這兩種類中實現所有三種方法,這種方式在這種情況下會失敗多態性的目的。 – Naveen