views:

164

answers:

6

what is the description or meaning of this: for example:

class test;

class test
{
  .....
};
+3  A: 

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.

phimuemue
A: 

Ehm, the question is not very clear. However, the code supplied declares a class test and defines it below, omitting the actual members (...).

Mau
+1  A: 

The first line is what's called a forward declaration. It brings the name of the class into the current namespace without actually defining it.

bshields
A: 

The simple answer is that when you use the first form, you can then hold pointers or references to a class without needing the full implementation. This can be very useful for when two classes tightly interact and their implementations or definitions are hard to separate.

DeadMG
+17  A: 

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".

Ferruccio
+1 for discussing circular references.
Brian
@Ferruccio: How many passes does `gcc` use?
Lazer
Ferruccio
@Ferruccio: I thought multi pass is meant for parsing, not for optimization.
Tobias Langner
+6  A: 

Hello

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.

Tobias Langner
+1 for mentioning the reason one would want to use forward declarations...
rubenvb
The compiler-efficiency usage legitimate, but I think the circular reference usage is a better starting point when thinking about the purpose of forward references.
Brian