Why would one do this?
Because the compiler only knows names that have been declared. So if you want to use a class, you have to declare it. But if its definition depends on its user, a forward declaration can suffice if the user doesn't depend on the definitin of the class in turn, but just on its declaration (= name).
In particular, if the user just needs a pointer or referece, it doesn't depend on the definition. But in the cases listed (which do not claim to be exclusive, since it's a standard non-normative excerpt), the user depends on the definition of class T if
- an object of type T is defined (3.1), or
- T is used as the object type or array element type in a new-expression (5.3.4), or
- an lvalue-to-rvalue conversion is applied to a lvalue referring to an object of type T (4.1), or
- an expression is converted (either implicitly or explicitly) to type T (Clause 4, 5.2.3, 5.2.7, 5.2.9, 5.4),
or
- an expression that is not a null pointer constant, and has type other than void*, is converted to the
type pointer to T or reference to T using an implicit conversion (Clause 4), a dynamic_cast (5.2.7) or
a static_cast (5.2.9), or
- a class member access operator is applied to an expression of type T (5.2.5), or
- the typeid operator (5.2.8) or the sizeof operator (5.3.3) is applied to an operand of type T, or
- a function with a return type or argument type of type T is defined (3.1) or called (5.2.2), or
- a class with a base class of type T is defined (Clause 10), or
- an lvalue of type T is assigned to (5.17), or
- an exception-declaration has type T, reference to T, or pointer to T (15.3).
In these cases, a forward declaration will not suffice and you need to fully define it.
Is it needed?
Yes, in the cases where it is needed it is needed. In the following case it is, because both classes refer to each other.
class A;
class B {
// forward declaration needed
void f(A);
};
class A {
void f(B);
};
// "- a function with a return type or argument type of type T is defined"
void B::f(A) {
}
The member function definition required not only a declaration but also the definition of class A.
What are the benefits? Drawbacks?
The benefits are that your program compiles. The drawback is that you have polluted the scope with just another name. But that's the necessary evil of it.