2013-02-20 81 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