what is the description or meaning of this: for example:
class test;
class test
{
.....
};
C++ (like C) was designed to be implementable by a single-pass compiler. Forward references are necessary in cases where the compiler needs to know that a symbol refers to a class before the class is actually defined. The classic example of this is when two classes need to contain pointers to each other. i.e.
class B;
class A {
B* b;
};
class B {
A* a;
};
Without the forward reference to B, the compiler could not successfully parse the definition for A and you can't fix the problem by putting the definition of B before A.
In a language like C#, which needs a two-pass compiler, you don't need forward references
class A {
B b;
}
class B {
A a;
}
because the compiler's first pass simply picks up all symbol definitions. When the compiler makes its second pass, it can say "I know B is a class because I saw the definition on my first pass".
The compiler needs the definition of a class if member/methods of that class are accessed or if the size needs to be known. In other cases, a forward declaration is sufficient. This saves you compile time. Example:
class A {
B m_b;
C* m_ptrC;
};
For this class, you need the definition of B (size needed) and only the declaration of C (pointers have fixed size). You only need to include the header of B, not the one of C. A forward declaration of C is sufficient.
a.h:
#ifndef A_H
#define A_H
#include <b.h>
class C;
class A
{
B m_b;
C* m_ptrC;
}
#endif
The forward declaration of c (instead of including c.h which is also possible) saves you parsing c.h whenever you include a.h. Across a large project, this may save a lot of compile time. Another benefit is, that changes in c.h do not trigger a recompile for a in this case. I do not know if compiler recognize this if you include c.h instead of forward declaring it.
For more information, try understanding the pimpl-idiom (just google for it. you'll get lots of hits).
Of course - in a.cpp if you actually do something with the pointer to c (e.g. m_ptrC->Add()), you'll need to include c.h. But a.cpp is read only once where the header file is read n times with large n for classes that are used very often in large projects.
Forward declaration also allows for circular dependencies. Example:
class B;
class A {
B* m_ptrB;
}
class B {
A* m_ptrA;
}
Just remember - you can't use any information about size & methods if you use forward declarations. This is also the case with 2 classes including each other (one class does not need the forward reference though). I personally think circular references are bad style and you should avoid them if possible.
For additional information: C++ FAQ
Thank you for the comment about the circular dependencies, I simply forgot them.
First, the class is declared, then it is defined.
Declaration: It just tells the compiler: Ok, here's something (method, class, etc.), that can be used by the given name. It just binds the given name to something.
Definition: It tells the compiler: Ok, here's what (and how) the methods, classes, etc. actually do their stuff. If something is defined, then the compiler is caused to actually allocate space for it.
You might have a look at here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With