尝试使用具有不同方法签名的std :: function来理解多态类

时间:2018-04-29 18:47:35

标签: polymorphism std-function

我是一个相当新的人,我试图想出一个例子来帮助我理解多态性,类型擦除和std :: function的使用。

我试图通过创建这个示例类来理解,它可以接受一个基本值,然后是一个std :: function,然后对基值进行许多数学运算之一。

double multiplyValue(double baseVal, double multiplyBy) {
    return baseVal * multiplyBy;
}

double divideValue(double baseVal, double divideBy) {
    return baseVal / divideBy;
}

double subtractFromDividedValue(double baseVal, double subtract, double divideBy) {
    return subtract - (baseVal / divideBy);
}

double inverseSubtract(double baseVal, double subtract) {
    return -(baseVal - subtract);
}

class PrintValue
{
public:
    PrintValue(int baseVal, std::function<double(double, double)> modifierFunc) {
        this->baseVal = baseVal;
        this->modifierFunc = modifierFunc;
    }

    void print() {
        std::cout << "Value : " << modifierFunc(baseVal, 2) << "\n";
    }

private:
    int baseVal;
    std::function<double(double, double)> modifierFunc;
};

int main()
{
    PrintValue multiplyVal(2, multiplyValue);
    multiplyVal.print(); 

    PrintValue divideVal(2, divideValue);
    divideVal.print();

    system("pause");
    return 0;
}

我的PrintVal类使用multiplyValue divideValue和inverseSubtract,因为它们具有相同的方法签名 - 但是当我想要我的&#34; PrintValue&#34; class能够接受subtractFromDividedValue函数......这就是我感到困惑的地方!

另外,我注意到我已经硬编码&#34; 2&#34;作为方法参数传递到print()函数中的modifierFunc。

我希望能够动态地将不同数量的方法参数传递到类中,但是这里很困惑,因为subtractFromDividedValue具有比其他数学函数更多的参数。所以我认为我只需要创建一个接口,并为所有可能的参数排列重载类,这是正确的吗?

最终我只想要一个可以传递函数的类,动态修改&#34; baseValue&#34; ...

干杯

1 个答案:

答案 0 :(得分:0)

  

所以我认为我只需要创建一个接口,并为所有可能的参数排列重载类,这是正确的吗?

你有很多方法可以做到这一点,最好是尝试并看看它们是如何发展的 - 如果认为某些事情很有希望但你会陷入困境,那么在这里创建一个新问题。作为一种方法的示例,您可以使用baseVal进行修改,使用vector提供的可变数量的参数以及应用转换的函数...... < / p>

PrintValue(double baseVal, std::vector<double> otherParameters, std::function<double(double, std::vector<double>)> modifierFunc)
  : baseVal_{baseVal}, otherParams_{std::move(otherParameters)}
{ }

...你可以创建合适的功能,如......

double subtractFromDividedValue(double baseVal, const std::vector<double>& params) {
    double subtract = params.at(0), divideBy = params.at(1);
    return subtract - (baseVal / divideBy);
}

为了获得更大的灵活性,您可以在调用print时添加参数:

void print(const std::vector<double>& extraParams) {
    if (extraParams.size())
    {
        std::vector<double> allParams{ otherParams_.begin(), otherParams_.end() };
        for (double p : extraParams) 
            allParams.push_back(p);
        std::cout << "Value : " << modifierFunc(baseVal, allParams) << "\n";
    }
    else
        std::cout << "Value : " << modifierFunc(baseVal, otherParams_) << "\n";
}