what's the difference between:

// main.h
#ifndef X_H
#define X_H

#include "point.h"    // supposing that point.h contains the declaration of Point class

class MyClass
{
private:
Point m_Point;

//...
};
#endif

// main.cpp

#include "main.h"
//...

and

// main.h
#ifndef X_H
#define X_H

class Point;

class MyClass
{
private:
Point m_Point;

//...
};
#endif

// main.cpp

#include "main.h"
#include "point.h"
//...

i mean difference in performance, manners of writing and so on.., i already know that the first case is used to avoid circular referencing when used with pointers/references

Recommended Answers

All 4 Replies

you want to rename main.h to myclass.h so that the name of the file tells you what's in the file. Other than that, there is little, if any, difference between the two methods. It's all a matter of programming style. I prefer the first method when one header file depends on another.

struct Point;                       // forward reference
struct MyClass1{Point &p;}; // reference to Point (ok)
struct MyClass2{Point *p;};  // pointer to Point (ok)
strcut MyClass3{Point  p;};  // Pointer Object (compile error)

Forward reference are used to inform the compiler a name is valid and defined somewhere else. However if the size of the object is required or any of the methods are used, then the actual definition is required.

No difference in runtime performance although using forward reference may reduce compile time in some cases since the header files is not required.

First of all, the second case will not compile, because the compiler will say "invalid use of incomplete type 'Point'". When you forward declare a class, you just tell the compiler that there is a class called Point, defined later. Since it is not yet defined (thus, incomplete), the compiler can only accept that you declare variables or data members that are references or pointers to objects of that class, not direct objects of that class. So, I guess the intended example was:

// myclass.h
#ifndef MYCLASS_H
#define MYCLASS_H

class Point;

class MyClass
{
private:
Point* m_Point; //notice the pointer to Point, not Point directly.

//...
};
#endif

// myclass.cpp

#include "myclass.h"
#include "point.h"
//...

>>difference in performance
Absolutely none. At least, not at run-time, and not in this simple example. The second case can reduce compilation times (i.e. fewer header dependencies lead to less code to compile in general, which reduces the overall compilation time). It can also lead to some increase in performance if several other measures are taken, which is beyond what I could explain here. In the basic cases, as shown above, it leads to no performance increase whatsoever.

However, since the second case forces you to hold the object m_Point by reference or pointer, there will be an extra level of indirection (i.e. you have to dereference the pointer to get to the object). That will be slightly slower than being able to store m_Point by value (as in the first case). But if you have to store m_Point by reference or pointer anyways, then it makes no difference.

>>manners of writing
It makes very little difference. That certainly does not factor into the decision of using one versus the other. See below.

>>and so on..
Assuming that you don't have a circular referencing problem (i.e. you _can_ use either one of the solutions), then there are a few reasons why you could prefer the second over the first method. In the second case, with forward-declaration, you don't need to include the header for Point. This is an advantage if you look at #inclusion as a copy-paste operation (which it basically is). When you include a header, the compiler fetches that header file, and copies it entirely in the place where the #include statement was (and then does the same for headers that that header includes, and so on, so forth). After having done all this (called preprocessing), the compiler will compile all the code (essentially as one big source-code file). It does so for every cpp file that you compile (called a translation unit). If you can reduce the amount of headers that you include in one header file, you reduce the compilation time of all the code that includes this header file. So, if you can avoid including a header by using a forward-declaration, do it. In large projects, it makes a real difference.

The second reason is the so-called PImpl idiom (or Cheshire Cat). This idiom basically relies on this forward-declaration mechanism to encapsulate a class completely and opaquely. This is important for many reasons beyond the scope of this post, but you are welcomed to look into it. In your simple example, you could notice that with the second solution, you can decide to distribute your code for the MyClass class without distributing the code for the Point class (by distributing the header myclass.h and the compiled code for myclass.cpp). Since the myclass.h header does not depend on point.h, you don't need to distribute it if you don't want to. You can basically hide-away all the implementation details in an opaque fashion, that's what the PImpl idiom is all about.

The main reason for choosing the first solution is to avoid having to store the object by reference or pointer, which increases performance and robustness.

So, in conclusion, it is a tough choice between performance and robustness, or maintainability and reduced compilation times. There is no black and white answer to this.

>>you want to rename main.h to myclass.h so that the name of the file tells you what's in the file
i always do this, but this was just an example and no other name came though my mind :D

thx again to all of you for a clear explanation
oh, and one more question, how do i mark a post as Solved?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.