Reputation: 486
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.
Upvotes: 0
Views: 232
Reputation: 6145
You have circular includes here:
AlghoritmState.hpp
is #include
ing 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.
Upvotes: 1