使用引用实现State Pattern

时间:2013-02-20 23:03:30

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

我正在尝试重构我的代码,除其他外,应用状态模式。我不仅仅是一名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)

任何提示都表示赞赏。

1 个答案:

答案 0 :(得分:1)

你在这里有通告:

AlghoritmState.hpp #includeFaceRegion.hpp,反之亦然。对于包含警戒,这意味着一个标题将看到另一个,但不是另一种方式。

您的问题是您在AlghoritmState中使用了FaceRegion,反之亦然。 AlghoritmState是一个接口,因此您应该删除成员变量并将其添加到实现HaarClassifierState

通过这种方式你可以这样包括:

  • FaceRegion包括AlghoritmState
  • HaarClassifierState包括FaceRegionAlghoritmState

正如您所看到的,您没有更多周期,编译问题就会消失。

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