c++ - 使用引用实现状态模式

标签 c++ inheritance design-patterns reference state-pattern

我正在尝试重构我的代码,其中包括应用状态模式。我更像是一名 Java 程序员,所以请保持友善 ;) 所以,这里我有我的基础状态类,没什么特别的:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include "FaceRegion.hpp"

class AlghorithmState {
public:
    AlghorithmState(FaceRegion context);
    virtual ~AlghorithmState();
    virtual cv::Mat processImage(cv::Mat frame) = 0;

private:
    FaceRegion CONTEXT;

};

和其中一个子状态:

class HaarClassifierState : public AlghorithmState {
public:
    HaarClassifierState(FaceRegion context);
    virtual ~HaarClassifierState();
    cv::Mat processImage(cv::Mat frame);
};

然后是 Context 类,它保存当前状态并在其 fromImage 方法/函数中调用 processImage:

#include "AlghoritmState.hpp"
using namespace cv;

class FaceRegion {
public:
    FaceRegion();
    virtual ~FaceRegion();
    Mat fromImage(Mat& image);
    void setAlghoritmState(AlghorithmState state); // line 10
private:
    AlghorithmState alghoritm; //line 
}

问题是,当我尝试编译这段代码时,第 10 行出现以下错误

In file included from AlghoritmState.hpp:15:0,
                 from FaceRegion.hpp:10,
                 from newmain.cpp:93:
FaceRegion.hpp:35:28: error: ‘AlghorithmState’ has not been declared
FaceRegion.hpp:39:5: error: ‘AlghorithmState’ does not name a type

我做错了什么?我尝试在 CONTEXT 类头文件中添加 AlghoritmState 的不完整类声明,但它只会引发另一个错误:

In file included from AlghoritmState.hpp:15:0,
                 from FaceRegion.hpp:10,
                 from newmain.cpp:93:
FaceRegion.hpp:40:21: error: field ‘alghoritm’ has incomplete type
FaceRegion.hpp:36:10: error: cannot declare parameter ‘state’ to be of abstract type ‘AlghorithmState’
In file included from FaceRegion.hpp:10:0,
                 from newmain.cpp:93:
AlghoritmState.hpp:17:7: note:   because the following virtual functions are pure within ‘AlghorithmState’:
AlghoritmState.hpp:21:21: note:     virtual cv::Mat AlghorithmState::processImage(cv::Mat)

感谢任何提示。

最佳答案

你在这里有通告:

AlghoritmState.hpp#includeing FaceRegion.hpp,反之亦然。使用 include guards 这意味着一个 header 将看到另一个 header ,但不会以另一种方式看到。

您的问题是您在 FaceRegion 中同时使用了 AlghoritmState,反之亦然。 AlghoritmState 是一个接口(interface),因此您应该将成员变量放在那里并将其添加到实现中,即 HaarClassifierState

这样你就可以像这样包含:

  • FaceRegion 包括 AlghoritmState
  • HaarClassifierState 包括FaceRegionAlghoritmState

如您所见,您没有更多的循环,编译问题将消失。

重要: 您当前正在按值存储对象。当您对继承的对象执行此操作时,它们很容易出现 slicing这意味着您最终可能会得到一个比它应该的小的对象,从而导致令人讨厌的事情发生(UB)。因此,在任何情况下都应该停止将对象父类(super class)存储为值,而应将它们存储为指针。 (这当然会导致我们遇到变量所有权的问题,但这是另一个问题)。因此,如果它是存储在那里的实际父类(super class)型,则只有父类(super class)型的成员变量。

关于c++ - 使用引用实现状态模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14991598/

相关文章:

c++ - NetBeans - 两个项目 - 一个找不到要包含的文件 (C++)

c++ - 替换文件中间的文本

c++ - 遍历映射 vector ,并在满足条件时插入拷贝

ios - 如何将派生类方法委托(delegate)给协议(protocol)方法?

javascript - DI 设计挑战与创建实例的类

c++ - 我可以在调用 WSAStartup() 之前创建一个套接字实例吗?

ruby-on-rails - 如何在不实例化 Ruby 中的 A 对象的情况下确定类 A 是否继承自类 B?

javascript - 使用单个全局命名空间,如何从工具的方法访问命名空间的属性/方法?

design-patterns - DataAdapter 使用外观模式还是适配器模式。

design-patterns - 事件驱动逻辑的设计模式