2013-02-20 80 views
0

我试图重构我的代码,其中包括应用状态模式。我更多的是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类,它保存当前状态,并调用processImage来就可以了其fromImage方法/函数中:

#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 
} 

的问题是,当我尝试编译这段代码,我GE t第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 

我做错了什么?我尝试添加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

你有圆形包括在这里:

AlghoritmState.hpp#include荷兰国际集团FaceRegion.hpp,反之亦然。在包含守卫的情况下,这意味着一个标题将会看到另一个标题,而不是其他方式。

您的问题是,您在FaceRegion和其他方式使用AlghoritmState。该AlghoritmState是一个接口,所以你应该有下降的成员变量并将其添加到实施,HaarClassifierState

这样,你就包含这样的:

  • FaceRegion包括AlghoritmState
  • HaarClassifierState包括FaceRegionAlghoritmState

正如你所看到的,你没有更多的周期和编译问题将不见了。

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

+0

非常感谢您的解释,这个问题让我头痛:) 回到你的笔记,我开始重写它使用引用,但陷入另一个障碍,你可以看看这个? 因此,它是这样的:在HaarClassifierState中的 。hpp: 'public: HaarClassifierState(FaceRegion&context); virtual〜HaarClassifierState(); cv :: Mat processImage(cv :: Mat frame); 私人: FaceRegion和背景;' 在HaarClassifierState.cpp: 'HaarClassifierState :: HaarClassifierState(FaceRegion和背景):CONTEXT(上下文){}' – 2013-02-21 11:45:36

+0

而且,在FaceRegion.hpp: '类FaceRegion { 市民: void setAlghoritmState(AlghorithmState&state); private: AlghorithmState&algorithm; } 但是,我似乎无法初始化算法字段,因为我不能初始化初始化列表中的变量(或可以吗?): 'FaceRegion :: FaceRegion():algorithm (HaarClassifierState(* this)){}' 说: 错误:从类型为'HaarClassifierState'的右值的类型'AlghorithmState&'的非const引用无效初始化 – 2013-02-21 11:46:19