根据给定对象的类型更改类的行为

Joe*_*ont 3 c++ templates

我想设计一个通用的C++类,它定义一个operator()函数,该函数在某一点返回数学函数的值.但是,我希望该类能够使用已经operator()定义的对象或类将要插入的值表来实例化以提供值.我想到了以下方法:

class MathFunction
{
    MathFunction(Functor& function);
    MathFunction(Mat<double> interpolationValues);

    double operator()(double radius, double angle);
};
Run Code Online (Sandbox Code Playgroud)

构造函数可以设置成员变量,并double operator()可以使用switch语句来确定如何输出double我想要的.但这看起来非常不优雅.

这个类的模板化版本可能有用,但由于这两种方法不共享任何代码,这样做是否明智?模板版本究竟是如何设计的?

不确定我是否清楚.如果需要澄清,请发表评论.

编辑:虽然我选择了Useless的答案来完整,但我想强调dasblikenlight贡献的速度和清晰度.谢谢.

das*_*ght 6

这是使用策略模式的主要情况:根据传递给构造函数的参数,MathFunction应该实例化依赖于a Functor的策略对象,或者依赖于插值值列表的策略对象.然后调用operator ()应该将调用转发给策略,并通过公共虚函数的实现获得结果:

class MathFunction {
    struct Strategy {
        virtual double Calculate(double radius, double angle)=0;
        virtual ~Strategy(){}
    };
    class FunctorStrategy : public Strategy {
        Functor& _function;
    public:
        FunctorStrategy(Functor& function)  : _function(function) {}
        virtual double Calculate(double radius, double angle) {
            return _function(radius, angle);
        }
    }
    class InterpolationStrategy : public Strategy {
        Mat<double> _interpolationValues;
    public:
        InterpolationStrategy (Mat<double> interpolationValues) 
        : _interpolationValues(interpolationValues) {}
        virtual double Calculate(double radius, double angle) {
            return ...; // Use _interpolationValues to do calculation
        }
    };
    unique_ptr<Strategy> _strategy;
public:
    MathFunction(Functor& function)
    : _strategy(new FunctorStrategy(function)) {}
    MathFunction(Mat<double> interpolationValues)
    : _strategy(new InterpolationStrategy(interpolationValues)) {}
    // And now for the complicated part:
    double operator()(double radius, double angle) {
        return _strategy->Calculate(radius, angle); // TA-DA!!!
    }
};
Run Code Online (Sandbox Code Playgroud)

  • 好的答案和建议.甚至_better_如果`_strategy`被保存在某个智能指针中. (2认同)
  • @Joey:vilify比每次测量都更容易测量;-)与代码相比,`if(using_interpolation){interpolate_code; } else {call_that_can_be_inlined()}`,您可能会看到进行虚拟呼叫的成本.因此,在依赖代码中的虚拟调用之前,您应该考虑一下您希望成为瓶颈的问题.但是瓶颈并不总是出现在你预期的地方,而且正如dasb所说,如果计算本身很昂贵,那么呼叫机制就不会成为瓶颈.因此,不值得避免虚拟呼叫.至少,不是因为这个原因. (2认同)