当前,我在一个项目中,需要为硬件(Arduino)动态添加和删除传感器。
为此,我创建了一个名为“ Sensor”的基类以及每个传感器的派生类。此“传感器”类具有一个称为execute的虚拟方法,并且由于每个传感器都不相同,因此在每个派生类上都覆盖了此方法,因此每种类型都需要不同的执行方式。在此示例中,我使用了PIR,而DTH11具有派生类。
当需要添加传感器时,硬件将从服务器接收一个字符串,然后从该接收的字符串中创建适当的传感器。为了简单地回答这个问题,我只是在main()方法上手动完成了。
要存储传感器,我使用的是std :: list,有时会调用execute()方法。
但是,始终执行基类(Sensor)的方法,而不是下面结果和预期结果所示的交付类。
class Sensor
{
protected:
int GPIO;
char* name;
public:
virtual void execute() {std::cout << "This is sensor"} ;
int getGPIO() const;
void setGPIO(int);
char* getName() const;
void setName(char*);
Sensor(int sensorGPIO, char* sensorName) {//};
};
class PIR : public Sensor {
public:
void execute(){std::cout << "This is PIR"};
PIR(int gpio) : Sensor(gpio, "pir"){//};
};
class DHT11 : public Sensor {
public:
void execute() {std::cout << "This is DHT11"};
DHT11(int gpio) : Sensor(gpio, "dht11"){//};
};
class SensorFactory
{
public:
SensorFactory(){};
Sensor createSensor(char* sensorString, int gpio)
{
if(strcmp(sensorString, "pir") == 0)
{
return PIR(gpio);
}
else if(strcmp(sensorString, "dht11") == 0)
{
return DTH11(gpio);
}
};
};
int main()
{
std::list<Sensor> sensors;
SensorFactory factory();
Sensor s1 = factory.createSensor("pir", 10);
Sensor s2 = factory.createSensor("dth11", 12);
sensors.push_front(s1);
sensors.push_front(s2);
std::list<Sensor>::iterator i = sensores.begin();
while (i != sensores.end())
{
(i)->execute();
++i;
}
/* Expected results
This is PIR
this is DHT11
*/
/* Result
This is sensor
This is sensor
*/
}
我也尝试过这个:
class Sensor
{
protected:
//
public:
virtual void execute() = 0;
//
};
但是我得到这个错误:
invalid abstract return type for member function
Sensor SensorFactory::createSensor(char*, int)
请记住,我是C ++的新手,所以这可能不是解决此问题的方法(实现)。
答案 0 :(得分:3)
问题是您要按值返回Sensor
。这样会创建原始传感器的副本,而没有其他扩展数据(也称为切片)。
使用:
std::unique_ptr<Sensor> createSensor(const std::string& sensorString, int gpio)
{
if(sensorString == "pir")
{
return std::make_unique<PIR>(gpio);
}
else if(sensorString == "dht11")
{
return std::make_unique<DTH11>(gpio);
}
};
将execute
作为纯虚函数使用时,您会看到它尝试通过创建Sensor
来创建副本。
存储传感器时,您也会遇到同样的问题,请改用唯一指针容器。