C ++ OOP体系结构:决定从基类声明对象还是继承基类

时间:2016-03-05 22:32:44

标签: c++ oop inheritance

我认为我的思绪在这一点上已经被炒了,我正在寻找一些关于如何在C ++中连接以下面向关注的类的帮助。

SensorBase的: 包含典型的传感器功能。大多数传感器共享相同的功能,但某些功能依赖于每个特定的传感器类,因此被声明为“虚拟”和“#34; (fe SensorBase::calcFactor()SensorBase::calcCelling())。

SensorThreshold& SensorTrend: 这些类扩展了SensorBase类的特定位的功能,具体取决于我是否想要跟踪当前传感器读数的阈值水平",或者我是否想跟踪一系列传感器读数的趋势。它们都以不同的方式实现" calcFactor()"。绝对有意义的是,这些类派生自SensorBase。

最后,我的混音发生在这里: CO2Sensor,NH3Sensor,O2Sensor等: 这些是" Xgas"传感器类(从现在起将被称为XSensor组)。对于每个传感器,我可能需要跟踪阈值,或获取值的趋势,或两者。该声明表明我可以声明一个(或两个)SensorThreshold / SensorTrend对象。

问题(和扭曲)是每个XSsensor需要重新定义SensorBase :: calcCelling()函数。所以想到这一点似乎从SensorThreshold或SensorTrend(作为公共虚拟来避免"钻石问题")中获取XGasSensor会有所帮助。但后来我不知道会调用哪个SensorThreshold :: calcCelling()和SensorTrend :: calcCelling()。 2具有相同的实现,但可以使用不同的值作为param调用。

如果我没有弄错,编译器应该在这里抛出一个错误并中止编译。但是,我无法从每个XGasSensor实现calcCelling()。

以上内容包含在以下内容中

class SensorBase
{
    public:
        virtual calcFactor();
        virtual calcCelling();
};

class SensorThreshold : virtual public SensorBase
{
    public:
        calcFactor();
        calcCelling();
};

class SensorTrend : virtual public SensorBase
{
    public:
        calcFactor();
        calcCelling();
};

然后

class CO2Sensor
{
    public:
        SensorThreshold sensorThres;
        SensorTrend sensorTrend;
        //but I cannot implement calcCelling() now
};

class CO2Sensor: public SensorThreshold , public SensorTrend ;
{
    public:
        calcCeilling(); //this would probably be "ambigious" error by the compiler
};

最后,我想问题是:我如何在SensorThreshold&amp ;;中实现SensorBase的位?每个XGasSensor中的SensorTrend和其他位?同时将我的XGasSensor实现基于SensorThreshold或SensorTrend或两者兼而有之?

编辑:

如果我说当前SensorThreshold和SensorTrend功能(如下所述)是SensorBase类的一部分,则上述内容可能会更有意义。因此,所有XGasSensors(稍后解释)都派生出SensorBase并实现calcCeiling()。这样,所有传感器都会跟踪阈值和趋势,这并不理想(因为并非所有传感器都需要阈值跟踪和趋势跟踪)。这就是为什么我试图将与阈值相关的功能与趋势相关的功能分开。

3 个答案:

答案 0 :(得分:1)

如果您尝试在calcCeiling()上调用此方法,则在XSensor中不覆盖XSensor,您将收到歧义错误。但是,您可以致电,只需通过限定即可从SensorThresholdSensorTrend调用此方法的任一版本。如果您在calcCeiling()次调用中覆盖XSensor,则对XSensor

明确无误
class CO2Sensor: public SensorThreshold , public SensorTrend
{
public:
    int calcCeiling() override {
        SensorThreshold::calcCeiling(); // this works
        SensorTrend::calcCeiling();  // this also works
    }
};

// by another object.
SensorBase* co2sensor = CreateSensor("CO2"); 
co2sensor->SensorThreshold::calcCeiling(); // non-ambiguous.
co2sensor->SensorTrend::calcCeiling(); // non-ambiguous.
co2sensor->calcCeiling(); // non-ambiguous (calls CO2Sensor::calcCeiling.)

我重新考虑你的继承模型,因为听起来你正试图在传感器上添加额外的功能,这听起来好像被描述为decorator pattern而不是多重继承。

答案 1 :(得分:1)

class SensorBase
{
    public:
        virtual calcFactor();
        virtual calcCelling();
};

class SensorThreshold : virtual public SensorBase
{
    public:
        calcFactor();
        Virtual calcCelling()
          {ThCeiling()}

    Protected:
          Virtual ThCeiling();
};

class SensorTrend : virtual public SensorBase
{
    public:
        calcFactor();
        Virtual calcCelling()
           {TrCeiling();}

    Protected:
        Virtual TrCeiling();
};

class CO2Sensor: public SensorThreshold , public SensorTrend ;
{
    Protected:
        TrCeiling();
        ThCeiling();
};

答案 2 :(得分:0)

我相信你说二氧化碳传感器可以实现阈值或趋势功能,并且可以在运行时确定创建这样的二氧化碳传感器。
因此,我建议采用一种方法,其中CO2传感器将包含指向基类的指针,可以在构建时对其进行初始化。

class CO2Sensor {
  private:
    SensorBase *sensorFunctionality;
  public:
    CO2Sensor( SensorBase *functionality);
    returnType calcCeiling() { return functionality->calcCeiling(); }
}

构造函数体将functionality参数分配给sensorFunctionality数据成员

如果许多传感器具有这种多功能行为的情况下你可能有一个名为MultifunctionSensor的类,它会执行此调度,然后从中派生出所有MultifunctionSensor类。