I'm having some problems trying to solve an apparent circular dependency in a project of mine. I'm working with OpenGL and FLTK to create a Robotics Simulation.

The problem is that I've created a Class FLGLWindow which basically manages a window with rendering capabilities. I also have a Menu class and a Cursor class and they both need information from an FLGLWindow object which is defined as a global variable in main.cpp.

Note: I have #ifndef protectors on all my .h files

So, I include FLGLWindow.h in GLCursor.h and viceversa (GLCursor.h in FLGLWindow.h) because the cursor needs the window properties for plotting and the window needs a cursor. What happens is that GLCursor doesn't recognize itself :(

1>GLCursor.cpp
1>h:\documents\technion\robotics cad project\code 0.4\flglwindow.h(91) : error C2146: syntax error : missing ';' before identifier 'MovementCursors'

How can I solve this?

P.S.:
GLCursor.h

#if !defined(AFX_GLCURSOR_H__F5770C07_1A04_49B2_B726_A2DE0035EB58__INCLUDED_)
#define AFX_GLCURSOR_H__F5770C07_1A04_49B2_B726_A2DE0035EB58__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
....
#include "FLGLWindow.h"
....

GLCursor.cpp

#include "GLCursor.h"

// ---> Window Parameters
extern FLGLWindow GL_MainWin;
....

FLGLWindow.h

// FLGLWindow.h: interface for the FLGLWindow class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_FLGLWINDOW_H__BB630CAB_E928_4E73_800F_2F2B12A40F12__INCLUDED_)
#define AFX_FLGLWINDOW_H__BB630CAB_E928_4E73_800F_2F2B12A40F12__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <math.h>
#include "Vector.h"
#include <FL/Fl.h>
#include <FL/Fl_Gl_Window.h>
#include <FL/gl.h>
#include <FL/glu.h>
#include "Texture.h"
#include "AuxiliaryFuncs.h"
#include "GLCursor.h"

#ifndef M_PI
#define M_PI 3.1415926
#endif

class FLGLWindow : public Fl_Gl_Window
{
public:
	// Constructors
	FLGLWindow(int x, int y, int w, int h, const char* WinName);
	FLGLWindow(int w, int h, const char* WinName);

	// Destructor
	virtual ~FLGLWindow();

	// Callbacks
	void InitFunction(void (*Func)(void)) { InitFunc=Func; }
	void RenderFunction(void (*Func)(void)) { RenderFunc=Func; }

	void SetBGColor(float Color1[], float Color2[]);

	double GetWorldParameter(int Parameter) {
		switch(Parameter) {
		case 1:	return ogLeft;
		case 2:	return ogRight;
		case 3:	return ogBottom;
		case 4:	return ogTop;
		case 5:	return WorldSize;
		default: return -1;
		}
	}

	int MouseX() { return mX; }
	int MouseY() { return mY; }

private:
	void draw();				// Overrided for FLTK
	int handle(int event);		// Overrided for FLTK

	void InitGL();
	void InitParameters();
	void ReshapeViewport();
	void Perspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
	void SetLights();

	void MoveCamera(int x, int y);
	void MoveCenter(int x, int y);
	void ChangeZoom(int x, int y);
	void UpdateCamera();

	// ---> World Parameters
	double WorldSize;
	double ogLeft, ogRight, ogBottom, ogTop, AspectRatio;

	// ---> Screen Parameters
	int mX, mY, OldX, OldY;

	// ---> Camera Parameters
	Vector CameraCenter, CameraPosition, CameraUp;
	double CameraDistance, MaxDistance, MinDistance;
	double Alpha, Beta;

	// ---> Transformation Matrices
	double ModelviewMatrix[16];
	double ProjectionMatrix[16];

	// ---> Colors & Materials
	float Zero[4], GradColor1[4], GradColor2[4];

	// ---> Movement Cursors
	GLCursor MovementCursors;

	// ---> Pointers to Additional Functions
	void (*InitFunc)();
	void (*RenderFunc)();
	bool (*KeybFunc)(unsigned char Key, int State, int x, int y);
	bool (*SpecKeybFunc)(int Key, int State, int x, int y);
	bool (*MouseFunc)(int Button, int State, int x, int y);

};

#endif // !defined(AFX_FLGLWINDOW_H__BB630CAB_E928_4E73_800F_2F2B12A40F12__INCLUDED_)

Dani AI

Generated

The C2146 error means the compiler sees GLCursor as an incomplete type when FLGLWindow declares MovementCursors by value. The root cause is the circular include: each header pulls in the other, include guards stop one of them and the type never gets defined. As and suggested, break the cycle by moving class definitions out of headers that need only a type name and by using a pointer or an owning smart pointer instead of an in‑place object.

A robust, modern approach (if the toolchain supports C++11+) is to forward‑declare GLCursor in FLGLWindow.h and hold a std::unique_ptr there; include the full GLCursor.h only in FLGLWindow.cpp to allocate and use it:

// FLGLWindow.h (excerpt)
#include <memory>
class GLCursor;            // forward declaration

class FLGLWindow : public Fl_Gl_Window {
public:
    FLGLWindow(...);
    ~FLGLWindow();
private:
    std::unique_ptr<GLCursor> MovementCursors; // no need for GLCursor definition here
};
// FLGLWindow.cpp (excerpt)
#include "FLGLWindow.h"
#include "GLCursor.h"

FLGLWindow::FLGLWindow(...) 
  : MovementCursors(std::make_unique<GLCursor>(this))
{ /* ... */ }

FLGLWindow::~FLGLWindow() = default;

Also forward‑declare class FLGLWindow; in GLCursor.h and accept a FLGLWindow* (or reference) in GLCursor constructor rather than relying on an extern global. This removes the need for mutual header inclusion and clarifies ownership. If C++11 is not available, use a raw pointer plus a clear ownership policy (allocate in the window ctor, delete in the destructor) or use boost::scoped_ptr/auto_ptr as appropriate.

Additional notes: forward declaration fails only when a complete type is required (e.g., a member by value, or inline methods that call the other class). If such inline use exists, move those member functions to the .cpp file so the full definition can be included there. For safety, prohibit implicit copying (delete copy ctor/assignment) or use smart pointers so dangling pointers and leaks are avoided.

Recommended Answers

All 2 Replies

This might be worth a shot: As you are going to only declare an object of the class GLCursor in your class FLGLWindow , and are not going to use its member functions directly (i.e, you are going to use the methods provided by GLCursor through the object you created in class FLGLWindow ), then forward declare the class GLCursor in this file. But make sure that you declare the object as a pointer or reference to the class GLCursor .

It should look something like this:

/*
   Something here
*/

// Your includes go here
#include ...

//#include "GLCursor.h"  //< You don't require this anymore, delete this

class GLCursor;          //< Replace the above with this forward declaration

/*
   Something here
*/

class FLGLWindow : public Fl_Gl_Window
{
public:
        /* ... Public methods ... */
private:

	// ---> Movement Cursors
	GLCursor* MovementCursors;

        /* ... Private Methods ... */

};

I have no idea whether this will help solve your problem, but its worth looking into.

try pre-declaring the classes in the header files, but that works only if the object you want to use is a pointer. So you would probably have to change GLCursor MovementCursors to a pointer GLCursor* MovementCursors; [edit]what ^^^ said :) [/edit]

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.