You are here:

C++/circular reference of header files

Advertisement


Question
i am developing a dynamic simulation program, i encounter a circular header file reference problem that i couldn't solve. I think that it is more explanatory to describe the problematic situation by referring actual class names rather than short names "A","B","C".

There are three classes to represent
 1) Body (in "kinetics.h/cpp")
 2) externalforcemoment (in "forces.h/cpp")
 3) Aero (in "aero.h/cpp")

body class contains pointers to force and aerodynamics objects, and aerodynamics class is derived from force class. Each class is declared and implemented in separate *.h, *.cpp file with #ifdef _XX_H guards. Below given shortened versions of 3 units

-----------------------
// aero.h
#if !defined(_AERO_H)
 #define _AERO_H
 #include "forces.h"
 #include "kinetics.h"
 class Body; // forward declaration
 class externalforcemoment; // forward declaration
 class Aero : public externalforcemoment {
   public:
       Aero(Body* b);
 };  
#endif

// aero.cpp
#include "aero.h"

Aero::Aero(Body* b) : externalforcemoment(b) {
};

-----------------------
// forces.h
#if !defined(_FORCES_H)
 #define _FORCES_H  
 #include "kinetics.h"
 class Body; // forward declaration  
 class externalforcemoment {
 public:
   Body * corp;
   double f[3], m[3];    
   externalforcemoment(Body* b);
 };  
#endif

// forces.cpp
#include "forces.h"
externalforcemoment::externalforcemoment(Body* b){
   corp = b;
   //b->agents.push_back(this);
};
-----------------------

#if !defined(_KINETICS_H)
 #define _KINETICS_H  
 #include <vector>    
 #include "forces.h"  
 #include "aero.h"
 
 class Aero; // forward declaration
 class externalforcemoment; // forward declaration  
 class Body {
   public:    
       Aero * aero;
       externalforcemoment *prop;
       void report(void);
       Body();
 };  
#endif

// kinetics.cpp
#include <iostream>
#include "kinetics.h"
using namespace std;
Body::Body(){
   prop = new externalforcemoment(this);
   aero = new Aero(this);
};

void Body::report(void){
   cout << "REPORTING Body\n";
   cout << "prop = " << prop << endl;
}
-----------------------
// main.cpp
#include <iostream>
#include <stdlib.h>

using namespace std;

#include "kinetics.h"

int main(int argc, char *argv[])
{
 Body b;  
 b.report();  
 system("PAUSE");   
 return 0;
}
-----------------------

i search internet for a solution to this problem, and find out that solution is to forward declare classes reported to be incomplete by compiler. (http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-38.11) gives detailed information on this issue. Forward declaration did not solve my problem. I think difference of my situation from the ones described in internet is inheritance relations of classes (Aero is descendant of externalforcemoment) that cause circular header reference. One solution seems to be implementing all 3 classes in same unit but i don't want this due extensibility requirement of code.

Thanks in advance

Hakan Tiftikci

additional information you required:
1) i am using mingw (gcc-3.2) compiler on windows 2000

compiler error messages vary but frequent one is

"base class 'externalforcemoment' has incomplete type"


Answer
Hakan Tiftikci, Thank you for your question.

I regret that I am unable to take the time to study your source code due to the volume of questions received.

Most "circular-reference" declaration problems can be resolved by using partial class declarations, as you observe. However, there are some that cannot be resolved using this technique. In such cases, one must sometimes design using pointers to classes, explicit contained class instances, or "friend" classes instead of using derived classes. I consider this a limitation of C++.

You might also want to post this question at www.experts-exchange.com, which is more advanced than allexperts.com, or in newsgroups.

David Spector

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


David Spector

Expertise

Highly knowledgeable in the C++ language, Visual C++ (MSVC), Windows API, documentation and other quality-assurance techniques, and debugging. Knowledgeable in MFC, COM, GUI design, and object-oriented design.

Experience

I have been a software engineer since 1965. I have been published. My specializations have been: biomedical programming, compiler implementation, and many kinds of Windows programming. I don't do Databases or other business-oriented stuff.

Publications
Windows?/DOS Developer's Journal, ACM SIGPLAN Notices, and Computer Science Press.

Education/Credentials
ICCP Systems Programming Certification
Master's degree equivalent in Computer Science

©2016 About.com. All rights reserved.