views:

106

answers:

4

In a .h if I have:

#pragma once

#include <xxxx.h>
#include "yyyy.h"

class AAAAAA;
class BBBBBB;

class ZZZZZZ
{
     public:

     // etc
 };

using class AAAAAA; is forward declaring a class right?

Why would one do this?

Is it needed?

What are the benefits? Drawbacks?

+3  A: 

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.

Johannes Schaub - litb
@Johannes - so if in a header file I want to use WWWW.h, I dont need to do an include "WWW.h" I can just do class WWW;?
ator
A: 

If you are only going to reference that type, there's no need to pull in the entire header where it's defined, just use a forward declaration which tells the compiler "this is defined" so the compiler, when it comes along its usage in that file, and can't resolve the symbol, doesn't freak out on you. It's one of those "I know what I'm doing" things.

jer
+3  A: 

If you refer to class by reference or pointer the compiler needs to know it exists but nothing else. Therefore all you need to do is forward declare it.

If a file calls methods on a class or refers to object instances (not references or pointers) then the definition of that type must by pulled in with a #include.

In a large codebase minimising #includes reduces compile time.

Forward declarations also help avoid circular #include problems.

morechilli
almost exactly what I was going to say.
San Jacinto
A: 

Forward declarations are essential when classes refer to each other. Here's a simple case:

class A;

class B {
     void f(A&);
};

class A {
     void f(B&);
};

You couldn't do this without a forward declaration. It's the same as when you have two mutually recursive functions, one of them must be forward declared.

Zack