带有继承的 C++ 工厂

标签 c++ design-patterns

目前,我正在进行一个项目,需要向硬件(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++ 比较陌生,因此这可能不是解决此问题的方法(实现)。

最佳答案

问题是您正在按值返回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 来创建拷贝。 存储传感器时也会遇到同样的问题,请改用唯一指针的容器。

关于带有继承的 C++ 工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53066625/

相关文章:

scala - 开源精心设计的 play-scala-slick 应用程序

azure - 我应该如何在 ASP.NET Core 2.0 API 中使用 HttpClient

C++ 函数返回在堆栈上创建的对象

c++ - 使用快速排序排序不会给出排序数组

c# - 仓库模式和工厂模式的区别

.net - 并发软件设计

python - 创建类二进制模式的算法

c++ - 使用 MS Visual Studio 2010 编译 C++ 程序不依赖于任何外部代码或可再发行组件

c++ - 为什么我不能删除用new创建的Ogre OverlaySystem?

c++ - 多线程:写入后先从另一个线程访问...我需要volatile吗?