Pregunta

I'm trying to refactor my code, among other things, applying state pattern. I'm more of a Java programmer, so please, be nice ;) So, here I've got my base state class, nothing fancy:

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

};

and one of child states:

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

And, then there's Context class, which holds current state and invokes processImage on it inside of its fromImage method/function:

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

The problem is, when I try compiling this code, I get following error on 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

What did I do wrong? I tried adding incomplete class declaration of AlghoritmState in the CONTEXT class header file but it only throws another error:

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)

Any hints appreciated.

¿Fue útil?

Solución

You have circular includes here:

AlghoritmState.hpp is #includeing FaceRegion.hpp and vice versa. With include guards this means that one header will see the other, but not the other way.

Your problem is that you use both AlghoritmState in the FaceRegion and the other way around. The AlghoritmState is a interface, so you should drop the member variable there and add it to the implementation, the HaarClassifierState

In that way you include like this:

  • FaceRegion include AlghoritmState
  • HaarClassifierState include FaceRegion and AlghoritmState

as you can see, you have no more cycles and you compilation problems will be gone.

Important: You are currently storing objects by value. When you do that with inherited objects they are prone to slicing which means that you might end up with a object that is smaller that it should be, leading to nasty stuff happening (UB). So you should in all cases stop storing objects super classes as values, and store them as pointers instead. (which ofcourse leads us to the problems of ownership of the variable, but that is for another question). So only have member variables of a super type if it is the actual super type that is stored there.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top