pre declare of class
Dear friends:
I have the following two classes.
#ifndef EQUATION_H
#define EQUATION_H
#include <stdlib.h>
#include <map>
class Mesh;
class Equation {
public:
Equation();
virtual ~Equation(){};
void associateMesh(Mesh * _pMesh){ pMesh = _pMesh;};
virtual void addsItsVariables4PostProcessing(map<string,const Variable*> & variablesMap)=0;
protected:
string name;
const Mesh* pMesh; };
#endif
Before the class Equation, there are a pre declare of class mesh. I do not understand why not to use a include to include the head file of Mesh class, what is the difference.
In the class member function "addsItsVariables", it use a paramter "map" which is not the class member, is this illegal?
Regards
ztdep
Junior Poster in Training
63 posts since Mar 2011
Reputation Points: 6
Solved Threads: 2
This "pre-declared class", as you call it, is what programmers call a "forward-declaration". A forward-declaration is useful when you need two classes to depend on each other (which would otherwise not be possible). Here is a simple example:
struct DogOwner {
Dog fido;
};
struct Dog {
DogOwner master;
};
Obviously, the above won't work because to declare DogOwner, you need Dog to be declared, but to declare Dog, you need DogOwner to be declared. This is called circular referencing (like circular logic), it simply cannot work that way. Forward-declarations offer a solution to this, as follows:
struct DogOwner; //forward-declare DogOwner
struct Dog {
DogOwner* master; //note that a forward-declared class can only be held by pointer or reference.
};
struct DogOwner {
Dog fido; //this works!
};
What a forward-declaration does is simply to give a promise to the compiler that there will be a real declaration of that class later on in the source code. This way, you can declare pointer and references to objects of that class before the compiler actually sees the declaration of that class (but, you cannot use objects of that class, only references and pointers).
So, the reason why you have this forward-declaration of Mesh in the code you posted is most likely because Mesh also needs the declaration of Equation.
Additional note: most of the time forward-declarations are avoidable and are often an indication of poor design of the software. So, be cautious in using them, explore other options before, it is likely that you will find a nicer solution that doesn't require a forward-declaration.
mike_2000_17
Posting Virtuoso
2,134 posts since Jul 2010
Reputation Points: 1,634
Solved Threads: 457
@ravenous, I totally agree. The need for a forward-declaration (from having circular dependencies) is usually indicative of some fundamental design flaw (i.e. not splitting responsibilities correctly leads to awkward dependencies, circular dependencies and/or too many dependencies). But you are right, aside from the purpose of resolving circular referencing problems, forward-declarations can be very useful to minimize the trail of header-file inclusions and thus reducing build times. Similarly, the Cheshire Cat idiom (or PImpl) uses forward-declarations to tuck away a dependency relating to the details of an implementation into the cpp, and thus, achieving a compilation firewall which is also very useful to minimize the needs for recompilation of source code.
mike_2000_17
Posting Virtuoso
2,134 posts since Jul 2010
Reputation Points: 1,634
Solved Threads: 457
This "pre-declared class", as you call it, is what programmers call a "forward-declaration". A forward-declaration is useful when you need two classes to depend on each other (which would otherwise not be possible). Here is a simple example:
struct DogOwner {
Dog fido;
};
struct Dog {
DogOwner master;
};
Obviously, the above won't work because to declare DogOwner, you need Dog to be declared, but to declare Dog, you need DogOwner to be declared. This is called circular referencing (like circular logic), it simply cannot work that way. Forward-declarations offer a solution to this, as follows:
struct DogOwner; //forward-declare DogOwner
struct Dog {
DogOwner* master; //note that a forward-declared class can only be held by pointer or reference.
};
struct DogOwner {
Dog fido; //this works!
};
What a forward-declaration does is simply to give a promise to the compiler that there will be a real declaration of that class later on in the source code. This way, you can declare pointer and references to objects of that class before the compiler actually sees the declaration of that class (but, you cannot use objects of that class, only references and pointers).
So, the reason why you have this forward-declaration of Mesh in the code you posted is most likely because Mesh also needs the declaration of Equation.
Additional note: most of the time forward-declarations are avoidable and are often an indication of poor design of the software. So, be cautious in using them, explore other options before, it is likely that you will find a nicer solution that doesn't require a forward-declaration.
Dear Mike:
Thank you very much for you feedback. Now i find some new problem about it. Your examples is very good, but if we declare the two structes in two different head file. how to use the forward-declaration.
ztdep
Junior Poster in Training
63 posts since Mar 2011
Reputation Points: 6
Solved Threads: 2