为了简化我的代码,我希望使用可以存储多个对象的数组,之后可以调用这些对象中的函数。
我创建了许多具有(部分)相同成员函数的类。当然,这些功能有不同的实现。我希望将这些对象放在一个数组中,之后我可以迭代调用这些函数。
我所拥有的是多个传感器,我们称之为Sensor1,Sensor2和Sensor3。它们都有一个名为readSensor()的函数和一个名为sensorData()的函数。 (第一个读取传感器,第二个返回一行html - 在我的实际软件中有10-12个传感器和4个这样的功能,因此我希望简化代码并使添加传感器更容易)。
所以我要做的就是这样:
Sensor1 sensor1;
Sensor2 sensor2;
Sensor3 sensor3;
byte nSensors = 3;
(type?) *sensorList[nSensors] // list of pointers to the sensors - don't know how to declare this.
void setup() { // yes, this is for Arduino.
sensorList[0] = &sensor1; // store the pointers to the class objects.
sensorList[1] = &sensor2;
sensorList[2] = &sensor3;
}
void readSensors () {
for (int i=1, i<nSnesors, i++) {
sensorList[i]->readSensor();
}
}
通过这种方式,我可以读取所有传感器,而无需写出所有传感器,并希望我不会忘记任何传感器。使代码更短,我可以在一个地方添加传感器。该阵列仅用于所有传感器具有的功能(虽然在不同的实现中具有相同的名称 - 毕竟这是不同的传感器)。这些对象也有一些特定于传感器的功能,可以在需要时直接调用。
这甚至可能吗?如果是这样,怎么样?
答案 0 :(得分:1)
是的,可以使用Polymorphism。
您可以定义基类(即Sensor
)和子类(即Sensor1
,Sensor2
和Sensor3
),其中Sensor
声明方法readSensor()
,并且所有3个子类都实现了此方法,但它们可以通过不同方式执行此操作。这样,您可以创建一个包含Sensor
类型元素的数组,并在每个元素上调用此方法,然后调用子类的已实现方法。
仅供参考:如果您愿意,也可以通过子类方法调用基类方法,以实现常见行为。
也许请查看此链接:tutorial
答案 1 :(得分:1)
您只需将运行时多态性用于该作业。
示例:
class SensorBase
{
public:
virtual void readSensor() = 0;
virtual void getData(char*) = 0;
};
class Sensor1: public SensorBase
{
void readSensor() { std::cout << "read for Sensor1 called" << std::endl; }
void getData(char* ptr) { std::cout << "get for Sensor1 called" << std::endl; }
};
class Sensor2: public SensorBase
{
void readSensor() { std::cout << "read for Sensor2 called" << std::endl; }
void getData(char* ptr) { std::cout << "get for Sensor2 called" << std::endl; }
};
// Static allocate objects, new is not a good idea for small embedded devices
// cause of significant overhead. Global objects are typically a design problem,
// but small embedded systems have different requirements ;)
Sensor1 sensor1;
Sensor2 sensor2;
// lets have array to objects, statically allocated
SensorBase* arr[] = { &sensor1, &sensor2 };
int main()
{
char htmlString[256];
for ( auto ptr: arr )
{
ptr->readSensor();
ptr->getData( htmlString );
}
}
您必须根据需要删除示例函数的内容。 std :: cout仅在此处用于让应用程序以可见输出方式运行,作为示例如何工作。
您在代码中使用setup
方法。这对于更大的系统来说可能是一个好主意,但不是在avr上!如果您在我给出的示例中使用静态分配,则代码将更小更快。如果你给编译器一些提示来存储你的一些数据字段或类在flash中,你可以加快它。有关该主题,请考虑#include <avr/pgmspace.h>
也许你必须用constexpr
构造函数编写类才能在flash中存储数据。必须使用虚拟方法注意:gcc不能将它们存储在flash中。这是一个非常古老的错误/设计问题,浪费了你的小设备的很多内存。切换到手臂设备的一个原因!见https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43745。如果您的代码中需要大量的多态类,这会使avr gcc无法使用。这个错误不会修复!