在许多不同的类中调用相同的函数

时间:2017-10-24 10:36:34

标签: c++ arrays class pointers arduino

为了简化我的代码,我希望使用可以存储多个对象的数组,之后可以调用这些对象中的函数。

我创建了许多具有(部分)相同成员函数的类。当然,这些功能有不同的实现。我希望将这些对象放在一个数组中,之后我可以迭代调用这些函数。

我所拥有的是多个传感器,我们称之为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();
  }
}

通过这种方式,我可以读取所有传感器,而无需写出所有传感器,并希望我不会忘记任何传感器。使代码更短,我可以在一个地方添加传感器。该阵列仅用于所有传感器具有的功能(虽然在不同的实现中具有相同的名称 - 毕竟这是不同的传感器)。这些对象也有一些特定于传感器的功能,可以在需要时直接调用。

这甚至可能吗?如果是这样,怎么样?

2 个答案:

答案 0 :(得分:1)

是的,可以使用Polymorphism

您可以定义基类(即Sensor)和子类(即Sensor1Sensor2Sensor3),其中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无法使用。这个错误不会修复!