Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Include in header file vs. forward-declare and include in .cpp

I have a class B, and I want to call members form class A. So:

1.

//A.h     class B;  class A  {  private:     B* m_p;  };   //a.cpp #include "B.h" 

2.

// A.h #include "B.h"  class A  {  private:      B * impl_;  };  

which way is better and is this two similar when a small project with not too much dependence involves?

like image 563
colddie Avatar asked Apr 05 '13 07:04

colddie


People also ask

Should I use forward declaration or include?

As the name itself implies, forward declaration is just a Declaration and not a definition. So, you will declare saying the compiler that it is a class and I just declaring it here and will provide you the definition when am gonna use it. So, normally you forward declare in the Header file and #include in the .

Why forward declare instead of include?

A forward declaration is much faster to parse than a whole header file that itself may include even more header files. Also, if you change something in the header file for class B, everything including that header will have to be recompiled.

What is forward declare in C++?

In C++, Forward declarations are usually used for Classes. In this, the class is pre-defined before its use so that it can be called and used by other classes that are defined before this. Example: // Forward Declaration class A class A; // Definition of class A class A{ // Body };

Why use forward declarations C++?

A forward declaration allows us to tell the compiler about the existence of an identifier before actually defining the identifier. In the case of functions, this allows us to tell the compiler about the existence of a function before we define the function's body.


2 Answers

Your first way of doing it means that in a.h, the existence of class B is known, but not its definition. This limits what you can do with B inside a.h. For example, you can have variables of type B *, but not variables of type B (because for a declaration of a variable of type B the compiler must be able to see the full definition of B). Also, if you have variables of type B *, you can't dereference the pointer (because for that, too, the definition of B must be known).

Therefore, your second choice – which doesn't have these problems – is preferred, and this is what most people use most of the time.

It's only special cases in which the first method may be useful. For example:

  • If the .h files include each other (but then you may get a number of further problems, also regarding include-guards; this is generally difficult and to be avoided);
  • If b.h is extremely large and complex, so you'd like to avoid including it wherever possible because it slows down the compilation process.
like image 134
jogojapan Avatar answered Oct 11 '22 23:10

jogojapan


Your first method is a forward declaration. Your second actually includes the class B.

When to use one over the other?

Use the first one when:

  • In the definition of A, you only have a pointer to B, i.e. not a member of B.
  • You never call any function of B from the definition of A. (i.e. all calls to member functions of B happen in the .cpp file where you actually implement A's member functions.)
  • You expect the interface or size of class B to change frequently, but not the interface of A. This way, if B changes, only the contents of a.cpp get recompiled, but a.h (and other files that include a.h) need not change.

Use the second one when:

  • You need to know the size of B. The compiler calculates a class's size using its class definition and the sizes of all its members. For example, if class A has a member that is of type B, then to calculate the size of A, the compiler needs to know the size of B; to know the size of B, you need to include b.h.
    • You need to call functions of class B. In order to know whether you're calling functions that actually exist, the compiler needs to know class B's interface, i.e. you need to include b.h.
like image 39
maditya Avatar answered Oct 11 '22 23:10

maditya