2017-06-17 121 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