考慮以下繼承和組合方案。具有非無效返回類型的虛函數
//例程序
#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.爲什麼派生類實現不會覆蓋根據非虛方法的類方法?
「是否可以使用非void返回類型的虛函數?」你試過了嗎? 「我可以給出一個虛擬的返回值,它將被派生類getter覆蓋嗎?」看來你錯過了一些對虛擬功能的基本理解。沒有「虛擬返回值」這樣的事情。它可以是被調用函數的返回值,也可以不是。你想要一個純虛函數嗎?這是一個在基類中沒有定義的虛函數。 https://en.wikipedia.org/wiki/Virtual_function#Abstract_classes_and_pure_virtual_functions – xaxxon
編譯器無法確定「G」是「HighPrecisionTapProcessing」對象的實例。例如,如果'G'是'StepPrecisionTapProcessing'的一個實例,那麼你期望'G-> getTapIndexHigh(index)'返回什麼?由於沒有函數'StepPrecisionTapProcessing :: getTapIndexHigh(uint)'的聲明,因此運行時會調用基本函數'TapProcessing :: getTapIndexHigh(uint)',您沒有爲其提供返回值的定義。編譯器需要函數'virtual uint TapProcessing :: getTapIndexHigh(uint)'來返回'uint'值。 –
你想要一個發生器實際包含特定類型的TapProcessing,但要有一個通用的接口和實現。我不確定你爲什麼要這樣做,但是如果這真的是你想要的,那麼我會讓你的TapProcesing基類在它的函數實現中拋出異常(如果編譯器仍然抱怨從未執行過的返回之前)你的派生類將被覆蓋。那樣的話,如果你在一個不被底層類型支持的Generator上調用了錯誤的函數,你將在運行時得到一個異常,使你不知道實際的底層類型。 – jschultz410