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;

};

と子の状態の1つ:

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

次に、現在の状態を保持し、fromImageメソッド/関数内でprocessImageを呼び出すContextクラスがあります。

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

ヒントをいただければ幸いです。

4

1 に答える 1

1

ここに循環インクルードがあります:

AlghoritmState.hpp#includeingでありFaceRegion.hpp、その逆です。インクルード ガードを使用すると、これは一方のヘッダーが他方のヘッダーを認識しますが、逆は認識しないことを意味します。

あなたの問題はAlghoritmStateFaceRegionとその逆の両方を使用することです。はAlghoritmStateインターフェイスなので、そこにメンバー変数をドロップして実装に追加する必要があります。HaarClassifierState

そのようにして、次のように含めます。

  • FaceRegion含むAlghoritmState
  • HaarClassifierState含めFaceRegionAlghoritmState

ご覧のとおり、サイクルがなくなり、コンパイルの問題がなくなります。

重要: 現在、値によってオブジェクトを格納しています。継承されたオブジェクトでこれを行うと、スライスが発生しやすくなります。つまり、オブジェクトが本来よりも小さくなり、厄介なことが発生する可能性があります (UB)。したがって、すべての場合において、オブジェクトのスーパークラスを値として保存するのをやめ、代わりにポインターとして保存する必要があります。(もちろん、変数の所有権の問題につながりますが、それは別の問題です)。したがって、そこに格納されているのが実際のスーパー タイプである場合にのみ、スーパー タイプのメンバー変数を使用してください。

于 2013-02-20T23:25:45.563 に答える