我知道之前可能已经问过这个问题,但我真的不知道要搜索什么,因为我甚至不确定我选择的标题。
我想要实现的目标: 如果我使用 getMeasurement(int timestep)并且传感器对象的地图中没有包含Integer值,则应使用特定于测量的方法 interpolate(。)插值(如果可能)。 ..)。 它应该从地图中获取正确的两个Measurements对象,用于超类Sensor中的插值并插入它们,但我不知道如何以及是否可以调用插值。也许使用Generics / Typename或设计模式。
Sensor someSensor = ...
Measurement measurementAt2 = someSensor.getMeasurement(2);
// should interpolate value if map measurements in someSensor not has the key 2
其他信息: ASensor ::测量只包含 AMeasurements 。 BSensor :: measurements 只包含 BMeasurements 。 ......这些测量包含不同的值类型,因此每个测量子类都需要以不同方式进行插值。
abstract class Sensor {
map<int, Measurement> measurements;
Measurement getMeasurement(int timestep);
}
class ASensor : Sensor {
...
}
class BSensor : Sensor {
...
}
abstract class Measurement {
...
}
class AMeasurement : Measurement {
AMeasurement interpolate(AMeasurement other, int timestep);
}
class BMeasurement : Measurement {
BMeasurement interpolate(BMeasurement other, int timestep);
}
如果我在Measurement for inheritance中添加一个抽象/虚拟方法 Measurement interpolated(Measurement other,int timestep),这个签名对子类不好,因为我需要检查类类型并投下另一个测量。
我很感激能够回答C ++ 11中的代码,我目前正在使用它。
编辑:如果需要此信息,子类ASensor + AMeasurement,BSensor + BMeasurement,...都是独立加载的插件。
EDIT2:添加了方法的返回类型(我忘了)。
答案 0 :(得分:0)
我不完全确定你的问题,但在c ++中我可以获得返回值协方差。也许这样的事情可以帮到你(见评论):
#include <iostream>
using namespace std;
struct Measurement //Abstract
{
virtual int apply(int timestep) const = 0;
virtual std::string name() const = 0;
protected:
virtual ~Measurement(){}
//...virtual Meas... etc
};
struct AMeasurement : Measurement //Implements Measurement for sensorA
{
std::string name() const override{ return "AMeasurement"; }
int apply(int timestep) const override
{
return timestep * 10;
}
};
struct BMeasurement : Measurement //Implements Measurement for sensorB
{
std::string name() const override{ return "BMeasurement"; }
int apply(int timestep) const override
{
return timestep * 20;
}
};
struct MeasurementProvider //Provides measurement
{
virtual const Measurement& getMeasurement() const = 0;
//...etc
protected:
virtual ~MeasurementProvider(){}
};
//Generalized measurement provider.
// Covariance ensure correct measurement used. Currently most basic
// implementation. Can elaborate
template <class MeasurementType>
struct GenMeasurementProvider : MeasurementProvider
{
//NOTE: MeasureType derived from Measurement, hence covariance...
const MeasurementType& getMeasurement() const override{return m_;}
MeasurementType m_;
};
// Perhaps Sensor is just a generalized Provider.
struct SensorA : GenMeasurementProvider<AMeasurement>
{
};
// Interpolate using provider instead of actual measurement to
// allow for covariance.
void interpolate(const MeasurementProvider& provider, int timestep)
{
//return type allows covariance, therefore apply to be
// called on correct type
auto const& measurement = provider.getMeasurement();
std::cout << "Result of measurement " << measurement.name()
<< ":" << measurement.apply(timestep) << std::endl;
}
int main() {
const int timestep = 100;
interpolate(GenMeasurementProvider<AMeasurement>{}, timestep);
interpolate(GenMeasurementProvider<BMeasurement>{}, timestep);
interpolate(SensorA{}, timestep);
return 0;
}
我已经省略了许多细节,我可能会更清晰地着色。
答案 1 :(得分:0)
如果您的问题是interpolate()
的签名,我想您可以根据派生类转换模板类中的Measurement
;
template <typename Derived>
class Measurement {
Derived interpolate (Derived other, int timestep)
{ /* do something */ }
};
class AMeasurement : Measurement<AMeasurement> {
// ...
};
class BMeasurement : Measurement<BMeasurement> {
// ...
};
p.s:抱歉我的英语不好
答案 2 :(得分:0)
如果您在getMeasurement
纯虚拟中使用Sensor
函数,那么您就不需要基类中的map
。然后由Sensor
的实现来存储它们自己类型的测量值并在它们之间进行插值。您可以提供模板类来完成所有工作:
class Sensor {
public:
virtual std::unique_ptr<Measurement> getMeasurement(int timestep) const = 0;
};
template<typename M>
class BasicSensor : public Sensor {
std::map<int, M> measurements;
public:
std::unique_ptr<Measurement> getMeasurement(int timestep) const override {
auto itr = measurements.lower_bound(timestep);
if (itr == measurements.end()) // Cant find measurement equal or later
return nullptr; // than timestep so can't interpolate.
if (itr->first == timestep) // Found exact match so
return std::make_unique<M>(itr->second); // don't need to interpolate.
if (itr == measurements.begin()) // Can't find measurement before
return nullptr; // timestep so can't interpolate.
auto interpolated = std::prev(itr)->second.interpolate(itr->second, timestep);
// Copy to smart-pointer to avoid slicing
return std::make_unique<M>(interpolated);
}
void setMeasurement(int timestep, const M& m) {
measurements[timestep] = m;
}
};
class ASensor : public BasicSensor<AMeasurement> {};
class BSensor : public BasicSensor<BMeasurement> {};