C++ OOP 体系结构:决定是从基类声明对象还是继承基类
C++ OOP architecture: deciding between declaring an object from a base class or inheriting the base class
我认为我的头脑在这一点上是炸的,我正在寻找一些帮助,以了解如何在C++中连接以下面向关注的类。
传感器底座:包含典型的传感器功能。大多数传感器共享相同的功能,但某些功能依赖于每个特定的传感器类别,因此声明为"虚拟"(FE SensorBase::calcFactor()
和SensorBase::calcCelling()
)。
SensorThreshold & SensorTrend:这些类仅扩展了 SensorBase 类的特定位的功能,具体取决于我是要根据"阈值水平"跟踪当前传感器读数,还是要跟踪传感器读数序列的趋势。它们都实现了不同的"calcFactor()"。这些类派生自 SensorBase 是绝对有意义的。
最后,我的混淆发生在这里:CO2传感器,NH3传感器,O2传感器等:这些是"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 类的一部分,上述内容可能更有意义。因此,所有XGasSensors(稍后也将解释)都派生了SensorBase并实现calcCeiling()
。这样,所有传感器都会跟踪阈值和趋势,这并不理想(因为并非所有传感器都需要阈值跟踪和趋势跟踪)。这就是为什么我试图将与阈值相关的功能与趋势相关的功能分开。
如果不覆盖XSensor
中的calcCeiling()
,如果尝试在XSensor
上调用此方法,则会出现歧义错误。 但是,你可以调用 你可以从SensorThreshold
调用此方法的任一版本,也可以通过限定它来调用此方法SensorTrend
。 如果您在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.)
我会重新考虑您的继承模型,因为听起来您正在尝试向传感器添加其他功能,这听起来比多重继承更适合描述为装饰器模式。
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();
};
我相信你是说 CO2 传感器可以实现阈值或趋势功能,这将在运行时创建此类 CO2 传感器时确定。
因此,我建议一种方法,其中CO2传感器将包含指向基类的指针,该指针可以在构造时进行初始化。
class CO2Sensor {
private:
SensorBase *sensorFunctionality;
public:
CO2Sensor( SensorBase *functionality);
returnType calcCeiling() { return functionality->calcCeiling(); }
}
构造函数主体会将functionality
参数分配给sensorFunctionality
数据成员
如果许多传感器具有这种多功能行为,则可能有一个名为MultifunctionSensor的类,该类执行此调度,然后让所有MultifunctionSensor类都从中派生。
- 将子类方法声明为基类的友元
- 是否可以使用 using 将基类中的公共成员重新声明为派生类中的私有成员?
- 基类可以声明虚拟方法但不定义它吗?仍然在派生类中定义
- 从模板基类派生是否在派生类声明的点实例化模板
- 从基类的唯一指针中声明派生类的类型
- C++ 多态性:如果派生类中的虚函数在基类中声明了常量,是否需要将其声明为常量
- 通过派生类模板参数指定基类模板参数之一。如何使用基类的 using 声明
- 如何将指针存储在实例变量中,该指针被声明为指向基类的指针
- 声明基类类型的指针,但随后通过指向子类来实例化它.这是良好的编程实践吗?
- 无法使用在模板化基类 [C++] 中声明的枚举编译代码
- 是否可以在C++中声明基类,以便只能通过创建函数创建从它派生的类
- 使用基类指针 - cpp 的适当声明设计接口
- 在基类主体内声明但通过派生类召集的函数
- 通过"a pointer of the base class"访问未在基类中声明的子类的方法或属性(动态)
- 在派生的C 类中,访问基类受保护成员作为公共的访问声明
- 在基类中使用派生类,而在基类之后声明派生类
- 在派生类或基类中,我应该在哪里声明友元类
- 在调用基类构造函数时声明默认构造函数
- C++ OOP 体系结构:决定是从基类声明对象还是继承基类
- 使用指定基类声明类