2

I'm trying to include files in my c++ program but I keep encountering the error:

ShapeVisitor.h:9:28: error: ‘Circle’ has not been declared

I think the problem is that the way the classes are structured, it results in a circular dependence. How do I solve this?

The class headers are below...

 //Circle.h
 #ifndef CIRCLE_H
 #define CIRCLE_H
 // headers, ...
 #include "Shape.h"
class Circle: public Shape { 
//class declaration 
}
#endif

//Shape.h
#ifndef SHAPE_H
#define SHAPE_H
// headers, ...
#include <iostream>

class Shape {  
//a certain method in the class declaration looks like this
virtual void accept(ShapeVisitor& v) = 0; 
//rest of class
}
#endif

//ShapeVisitor.h
#ifndef SHAPEVISITOR_H
#define SHAPEVISITOR_H
#include "Circle.h"
class ShapeVisitor {
//a method in the class looks like this:
virtual void visitCircle(Circle *s) = 0;
//rest of class
}
#endif

As you can see, circle includes shape, which includes shapevisitor, which again, includes circle.

Any ideas?

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
docaholic
  • 613
  • 9
  • 29
  • As you can see... I must be blind, I don't see it. What I see is no includes, so the Cyrcle is undeclared. –  Mar 30 '13 at 23:31
  • 3
    Your class definitions need semicolons. – chris Mar 30 '13 at 23:32
  • Maybe [this](http://stackoverflow.com/questions/14909997/why-arent-my-include-guards-preventing-recursive-inclusion-and-multiple-symbol) could help figuring out what's going on in detail – Andy Prowl Mar 30 '13 at 23:35

1 Answers1

5

ShapeVisitor.h does not need to include Circle.h, a forward declaration class Circle; will do. Function declarations do not require the full definitions of their argument and return types (not even if the return/arguments are by value!). Only the function's implementation file (in your case: ShapeVisitor.cpp) would need to include Circle.h.

This ancient (but still very true!) column by Herb Sutter is a nice reference.

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
  • 1
    @artlessnoise thanks for elaborating what a forward declaration is, added. But note that even if the function signature would have been `void visitCircle(Circle s)`, the header would not have been necessary! – TemplateRex Mar 30 '13 at 23:43
  • 1
    Ahh okay, thanks for the explaination! I'm assuming then, in my Shape class, I only need a forward declaration of "ShapeVisitor" as well then? – docaholic Mar 30 '13 at 23:45
  • @docaholic yes correct, but note that Circle.h does need to include Shape.h because a derived class needs the base class definition in order to be defined itself. – TemplateRex Mar 30 '13 at 23:47
  • Sorry, it is a while since I programmed in C++. Derivation or composition. – artless noise Mar 30 '13 at 23:50
  • Thanks rhalbersma, that really made a lot more sense. I'd upvote your answer twice if i could! – docaholic Mar 30 '13 at 23:58
  • @docaholic great to have been of help. – TemplateRex Mar 30 '13 at 23:59