Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Minimizing compilation dependencies - how ? 1

Status
Not open for further replies.

areza123

Programmer
Jul 4, 2002
60
IN
To demonstrate forward declarations -
I put up a simple structure consisting of 3 source files main.cc a.cc and b.cc

a.h
====
#include <iostream>
class A {
public:
void show();
};

I use a forward declaration of class A in b.h
b.h
====
#include <iostream>
class A; // forward declaration - no #include &quot;a.h&quot; here
class B {
public:
void showA(A *ptrA);
};

a.cc
=====
#include &quot;a.h&quot;
void A::show()
{
std::cout << &quot;Demonstrates minimum compilation dependencies&quot;;
}

By using the forward declaration in b.h effectively the #include &quot;a.h&quot;
has been moved from b.h to b.cc

b.cc
=====
#include &quot;b.h&quot;
#include &quot;a.h&quot;
void B::showA(A *ptrA)
{
std::cout << &quot;Calling show method of A&quot; << std::endl;
ptrA->show();
}

And finally...
main.cc
=======
#include &quot;a.h&quot;
#include &quot;b.h&quot;
int main()
{
B *ptrB = new B;
A *ptrA = new A;
ptrB->showA(ptrA);
return 1;
}

Effectively by using a forward declaration I have moved the #include &quot;a.h&quot; from b's header to the source file. How does the compilation dependency reduce ?

Cheers
 
>How does the compilation dependency reduce ?

Well you cant reduce it more as it looks today, simply because:
* main.cc needs a.h and b.h to instantate A and B.
* b.cc needs a.h to be able to operate on A

So naturally should a.h change, everything would need to be recompiled, even with your nice forward declaration.

However, the benefit would be apparent if you introduce a 3rd class C (in c.h/c.cc) that is only dependant on B (b.h).

With the forward declared A, c.cc would NOT need to be rebuilt even if a.h changes.

With a.h included in b.h then C would have to be rebuilt as well, even though it actually dont care about A.



/Per

if (typos) cout << &quot;My fingers are faster than my brain. Sorry for the typos.&quot;;
 
I'm not entirely sure what you are asking - the dependancy is reduced as the header file 'b.h' doesn't need to know about the header file 'a.h'.

You might also be able to extend this by replacing #include <iostream> with #include <iosfwd> if a forward declaration of the stream will suffice.

Another common trick is to use 'Pimpls' for private members of larger classes to further reduce dependancies.

Effectively you forward declare a pointer to a struct in the private declaration of your class

foo.h
-----
class X
{ private :
struct Ximpl *pimpl;
};

foo.c
-----
struct X::Ximpl
{// private members go here.
}

This has the advantage that private members are fully hidden and can be changed at will without having to recompile client code.

Also, types mentioned only in a class's implementation no longer need to be defined for client code which can further reduce #includes.

It does, however, carry a performance hit (as each access requires an extra level of indirection).
 
Another way to see it:

* Everything included in x.h is part of X' interface.
* Everything dependant on X'interface also become dependendant on x.h's includes, whether they want to or not.

You would wish to keep dependancies on a minimum and only depend of stuff you actually need.

One thing: Compile time reduction.
Another thing: It is easier to see how things relate.
A third thing: You might ask yourself &quot;What will break when I change X&quot;. The less stuff thats dependant on X the easier it is to find out.



/Per

if (typos) cout << &quot;My fingers are faster than my brain. Sorry for the typos.&quot;;
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top