考虑以下继承和组合方案。具有非无效返回类型的虚函数
//例程序
#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