crissilvaeng
crissilvaeng

Reputation: 165

Difference between include directive and forward declaration in C++

I must refactor an old code. One of its problems is that it exceeds on useless 'includes'. In the same project, I've seen the following syntax:

#include <AnyClass> //A system header
#include "AnotherAnyClass" //A application header

class AnotherClass;

class Class : public OneMoreClass
{

public:
    explicit Class();
    ~Class();

private:
    AnotherClass *m_anotherClass;

}

I'd like to figure out:

  1. What are the differences between a 'include "Class"' and a 'class Class'?
  2. When should the second method be used and how?

Upvotes: 6

Views: 1521

Answers (3)

JBL
JBL

Reputation: 12907

To understand the difference, you must understand why the compiler need the include in the first place.

The compiler must know the size of each class you declare. Thus it has to know the size of each member you added to the class. In the case of a non-pointer non-built-in member, the compiler has to see the definition of that member class, which is usually in a header that you must include. In the case of a pointer though, the compiler doesn't have to see the whole definition because whatever its type, a pointer is always of the same size on a given platform (usually 32 or 64 bits). So when the member is a pointer, the compiler only has to know the name, which can be done through forward declaration, i.e.

class AnotherClass;

Now, which one to use?

Keeping it short: Use forward declaration when you can, include when you must.

If your header can do fine with a forward declaration, you'll decrease your overall compilation time, because each header you include will have to be processed in every translation unit that contains it.

A common scheme is to forward declare in the header, and include the corresponding class in the associated .cpp.

Upvotes: 5

Marco A.
Marco A.

Reputation: 43662

Those are two different things:

#include <AnyClass>

this is a normal include for a header (or any type of textual) file. It is equivalent to pasting the content of the AnyClass file in the spot where you typed that inclusion directive (that's why include guards and/or compiler pragmas are often used to prevent multiple inclusions in the same file).

This syntax:

class AnotherClass;

is a forward declaration and it informs the compiler of the existence of AnotherClass class. It is useful in many scenarios, for e.g. suppose you have two classes where each one needs a pointer to the other:

class ClassB {
    ClassA* pointer_to_classA;
};
class ClassA {
    ClassB* pointer_to_classB;
};

the above code will generate an error: "error: unknown type name 'ClassA'" since you used a ClassA type without the compiler knowing what it is (yet). The compiler's parser only get to know ClassA's existence when it parses the beginning of the class declaration.

To have the above working you need a forward declaration:

class ClassA; // A ClassA type exists

class ClassB {
    ClassA* pointer_to_classA;
};
class ClassA {
    ClassB* pointer_to_classB;
};

Upvotes: 5

Nick Veys
Nick Veys

Reputation: 23939

Declaring a class like this:

class AnotherClass;

is called a Forward Declaration. It lets the compiler know about the existence of the class, in situations where knowning the details about the class aren't needed, like in the scenario you posted.

Generally if you aren't going to be using an instance of the class, you're just dealing with a pointer and not calling any methods on it, you don't need to know anything more than the class name. This can speed up compilation in large projects.

Upvotes: 7

Related Questions