【问题标题】:C++ OOP architecture: deciding between declaring an object from a base class or inheriting the base classC++ OOP 架构:决定是从基类声明对象还是继承基类
【发布时间】:2016-03-05 22:32:43
【问题描述】:

我觉得此时我的想法很糟糕,我正在寻求一些帮助,以了解如何在 C++ 中连接以下面向关注的类。

SensorBase: 包含典型的传感器功能。大多数传感器共享相同的功能,但其中一些功能依赖于每个特定的传感器类,因此被声明为“虚拟”(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 具有相同的实现,但可以使用不同的值作为参数调用。

如果我没记错的话,编译器应该在这里抛出错误并中止编译。但是,我无法从每个 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 和 SensorTrend 中实现 SensorBase 的位以及每个 XGasSensor 中的其他位?同时将我的 XGasSensor 实现基于 SensorThreshold 或 SensorTrend 或两者?

编辑:

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

【问题讨论】:

    标签: c++ oop inheritance


    【解决方案1】:

    如果不覆盖XSensor 中的calcCeiling(),如果您尝试在XSensor 上调用此方法,则会出现歧义错误。但是,您可以调用您可以从SensorThresholdSensorTrend 调用此方法的任一版本,只需对其进行限定即可。如果您在XSensor 中覆盖calcCeiling(),则对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

    【讨论】:

    • “装饰器模式”这个非常有趣(而且对我来说很新)的话题,我正在彻底研究它
    【解决方案2】:
    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();
    };
    

    【讨论】:

    • 有人可以格式化吗?不知道如何通过我的手机进行操作
    【解决方案3】:

    我相信您是说 CO2 传感器可以实现阈值或趋势功能,这将在运行时确定创建此类 CO2 传感器的时间。
    因此,我建议采用一种方法,其中 CO2 传感器将包含一个指向基类的指针,该基类可以在构造时进行初始化。

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

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

    如果许多传感器具有这种多重功能行为,您可能有一个名为 MultifunctionSensor 的类,它会执行此调度,然后让所有 MultifunctionSensor 类派生自它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-18
      • 2023-03-17
      • 2016-09-02
      • 1970-01-01
      • 2020-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多