3

Hi I am trying to forward declarate the cv::Mat class but I cant get it to work. It gives the message field 'frame' has incomplete type.

OpenGlImpl.h

namespace cv {
    class Mat;
}

class OpenGLImpl {

private:
   cv::Mat frame;

};

How should I properly forward declarate this?

Vern
  • 147
  • 2
  • 14
  • Why does not #include work? – ChronoTrigger Jul 04 '13 at 10:21
  • #include "opencv2/core/core.hpp" – banuj Jul 04 '13 at 10:21
  • 2
    You cannot forward declare member variable (or base classes) cos it affects the size of your class. You can things you will use as pointers etc which won't affect the size – doctorlove Jul 04 '13 at 10:25
  • 2
    This question http://stackoverflow.com/questions/553682/when-to-use-forward-declaration gives a clear list of when and what you can/cannot forward declare – doctorlove Jul 04 '13 at 10:27
  • ChronoTrigger and banuj I do not want to include all those methods into my header. I want to keep things seperated and only use the methods in my cpp file where I will include the headers. – Vern Jul 04 '13 at 10:30
  • The accepted answer is correct, but don't forget cv::Mat has its own reference counting semantics. You might consider placing this impl inside your cpp source w/opencv includes, and rethink the public header where it contains no reference at all to cv::Mat. – assem Jul 04 '13 at 13:41

2 Answers2

9

You cannot use a forward declaration here. The compiler needs to have the definition of cv::Mat in order for it to be a data member of OpenGLImpl.

If you want to avoid this constraint, you could have OpneGLImpl hold a (smart) pointer to cv::Mat:

#include <memory>

namespace cv {
    class Mat;
}

class OpenGLImpl {

private:
   std::unique_ptr<cv::Mat> frame;

};

You can then instantiate the cv::Mat owned by the unique_ptr in an implementation file.

Note that a reference would also work with a forward declaration, but it is unlikely you need refernce semantics here.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
3

§ 3.9.5

A class that has been declared but not defined, or an array of unknown size or of incomplete element type, is an incompletely-defined object type.43 Incompletely-defined object types and the void types are incomplete types (3.9.1). Objects shall not be defined to have an incomplete type.

struct X; // X is an incomplete type
X* xp;    // OK, xp is a pointer to an incomplete type. 

struct Y
{
   X x;   // ill-formed, X is incomplete type
}     

struct Z
{
   X* xp;   // OK, xp is a pointer to an incomplete type
}     


void foo() {
//  xp++; // ill-formed: X is incomplete
}

struct X { int i; }; // now X is a complete type

X x;           // OK, X is complete type, define an object is fine

void bar() {
  xp = &x;     // OK; type is “pointer to X”
}

void t()
{   
  xp++; // OK: X is complete
}
billz
  • 44,644
  • 9
  • 83
  • 100