继承的类函数比基类需要更多的输入

时间:2019-07-06 13:13:51

标签: c++

我有一些功能需要应用于3个不同变量(xyz)的不同域。通常,每个函数仅将变量之一作为输入。例如:

float myFunction(float val) { return val * 3.14159; }

这些函数可以是简单的常数乘法,插值,导数等。我想拥有一个vector,其中包含在不同域中定义的函数。例如,所有x函数都在std::vector<…> xFunctionsstd::vector<…> yFunctions等中。

现在,我需要增加一个函数的功能,以将所有三个变量用作输入,但我想将它们保留在vector s中。

这是一个例子

#include <limits>
#include <vector>
#include <memory>
#include <iostream>

class Model {
public:
  Model(float b1 = 0.0, float b2 = std::numeric_limits<float>::infinity())
      : lowerBound(b1), upperBound(b2) {}

  virtual float Function(float inp) { return 0.0; }

  float GetUpperBound() const { return upperBound; }

  float GetLowerBound() const { return lowerBound; }

protected:
  float lowerBound, upperBound;
};

class ConstantModel : public Model {
public:
  ConstantModel(float b1 = 0.0,
                float b2 = std::numeric_limits<float>::infinity(),
                float f = 0.0)
      : Model(b1, b2), factor(f) {}

  float Function(float inp) { return factor; }

private:
  float factor;
};

class LinearModel : public Model {
private:
  float interpFactor1, interpFactor2;
  float interpTerm;

public:
  LinearModel(float b1 = 0.0, float b2 = std::numeric_limits<float>::infinity(),
              float f1 = 0.0, float f2 = 0.0)
      : Model(b1, b2), interpFactor1(f1), interpFactor2(f2) {
    interpTerm = (interpFactor1 - interpFactor1) / (upperBound - lowerBound);
  }

  float Function(float inp) {
    return interpFactor1 + (inp - lowerBound) * interpTerm;
  }
};

class MultipleInputs : public Model {
private:
  float factor;

public:
  MultipleInputs(float b1 = 0.0,
                 float b2 = std::numeric_limits<float>::infinity(),
                 float f1 = 0.0)
      : Model(b1, b2), factor(f1) {}

  float Function(float inpX, float inpY, float inpZ) {
    return factor * (inpX + inpY + inpZ);
  }
};

int main() {
  // In practice I have xModels, yModels, zModels
  std::vector<std::unique_ptr<Model>> xModels;

  xModels.emplace_back(new ConstantModel(0.0, 1.0, 3.14159));
  xModels.emplace_back(new LinearModel(1.0, 2.0, 1.0, 2.0));
  xModels.emplace_back(new MultipleInputs(3.0, 4.0, -1.0));

  float xValue;
  float yValue(1.0), zValue(2.0);
  std::cin >> xValue;

  // Find the applicable function to use
  std::size_t i = 0;
  while (xModels[i]->GetUpperBound() < xValue) {
    ++i;
  }
  float result = xModels[i]->Function(xValue);
  std::cout << result << std::endl;
  ;

  return 0;
}

如果我输入0.5,则结果为3.14159。如果输入1.5,则结果为1。如果输入3.5,我希望答案为(3.5 + 1.0 + 2.0) * -1.0 = -6.5。但是,我得到了0,因为调用了函数Model::Function。这很合理,因为我只给出1个输入。如果我给出3个输入,则会得到预期的编译器错误“函数不带有3个参数”。

我开始使用decltype和运行时类型标识,但这让我觉得我做错了。使继承的类成员函数比基类接受更多输入的正确方法是什么?

更新

我修改了基类以使其具有重载的Function(float, float, float),然后使用typeid.hash_code()确定是否需要使用这样的1或3输入函数。

#include <limits>
#include <vector>
#include <memory>
#include <iostream>
#include <typeinfo>

class Model {
public:
    Model(float b1 = 0.0, float b2 = std::numeric_limits<float>::infinity()) :
        lowerBound(b1), upperBound(b2) {}
    virtual float Function(float inp) { return 0.0; }
    virtual float Function(float i1, float i2, float i3) { return 0.0; }
    float GetUpperBound() const { return upperBound; }
    float GetLowerBound() const { return lowerBound; }

protected:
    float lowerBound, upperBound;
};

class ConstantModel : public Model {
public:
    ConstantModel(float b1 = 0.0, float b2 = std::numeric_limits<float>::infinity(), float f = 0.0) :
        Model(b1, b2), factor(f) {}
        float Function(float inp) { return factor; }

private:
    float factor;
};

class LinearModel : public Model {

private:
    float interpFactor1, interpFactor2;
    float interpTerm;

public:
    LinearModel(float b1 = 0.0, float b2 = std::numeric_limits<float>::infinity(), float f1 = 0.0, float f2 = 0.0) :
        Model(b1, b2), interpFactor1(f1), interpFactor2(f2) {
        interpTerm = (interpFactor1 - interpFactor1) / (upperBound - lowerBound);
    }
    float Function(float inp) { return interpFactor1 + (inp - lowerBound) * interpTerm; }
};

class MultipleInputs : public Model {

private:
    float factor;

public:
    MultipleInputs(float b1 = 0.0, float b2 = std::numeric_limits<float>::infinity(), float f1 = 0.0) :
        Model(b1, b2), factor(f1) {}
    float Function(float inpX, float inpY, float inpZ) { return factor * (inpX + inpY + inpZ); }
};

int main() {

    // In practice I have xModels, yModels, zModels
    std::vector<std::unique_ptr<Model> > xModels;
    std::vector<std::size_t> tags;
    tags.emplace_back(typeid(Model).hash_code());
    tags.emplace_back(typeid(ConstantModel).hash_code());
    tags.emplace_back(typeid(LinearModel).hash_code());
    tags.emplace_back(typeid(MultipleInputs).hash_code());

    for (auto i : tags) {
        std::cout << i << std::endl;
    }

    xModels.emplace_back(new ConstantModel(0.0, 1.0, 3.14159));
    xModels.emplace_back(new LinearModel(1.0, 2.0, 1.0, 2.0));
    xModels.emplace_back(new MultipleInputs(3.0, 4.0, -1.0));

    float xValue;
    float yValue(1.0), zValue(2.0);
    std::cin >> xValue;

    // Find the applicable function to use
    std::size_t i = 0;
    while (xModels[i]->GetUpperBound() < xValue) {
        ++i;
    }
    float result;
    if (typeid(*xModels[i]).hash_code() == tags[3]) {
        result = xModels[i]->Function(xValue, yValue, zValue);
    }
    else {
        float result = xModels[i]->Function(xValue);
    }
    std::cout << result << std::endl;;

    return 0;
}

从某种意义上说,这是可行的,我可以在需要时获得3输入版本,但是感觉有更好的方法来实现。

1 个答案:

答案 0 :(得分:1)

  

让继承的类成员函数比基类接受更多输入的正确方法是什么?

不能用不同的签名重新定义虚拟函数,并且派生类必须根据基类的规范实现所有虚拟函数。如果您不能确保这一点,则说明您的设计存在问题,您想对其进行修改。

除了原始的继承函数之外,派生类还可以定义一个新的,不相关的函数。如果签名不同,则两个函数可能具有相同的名称,从而导致函数重载。