forward declaration..

qcpp's Avatar, Join Date: May 2009
Newbie Member
hello friends,
i am new to C++ i have a question,
say i have 2 classes in 2 files (in same directory) say... A.cpp A.h and B.cpp B.h
in B.cpp's public i.e. (Class B's public) i want to have an instance of Class A say A *test;
Now, my question is whether it is sufficient to include the file A.h in B.h ? or i also need to say Class A (as a forward declaration in B.h) in B.h ?
When to use the forward declaration ? when is it necessary ? is there any specific conditions ?
Thanks in Advance..
0
SaswatPadhi's Avatar, Join Date: May 2009
~ Б0ЯИ Τ0 С0δЭ ~
Quote:
Originally Posted by qcpp View Post
Now, my question is whether it is sufficient to include the file A.h in B.h or i also need to say Class A (as a forward declaration in B.h) in B.h ?
If you just need to use a pointer to A like A *test, then you should use forward declaration of A. Of course including A.h will also do the job, but will make the compilation process slower. If Class B inherits from A (implicitly or explicitly), then including A.h is a must.

Quote:
Originally Posted by qcpp View Post
When to use the forward declaration ?
Whenever possible, 'cuz it's faster.

Quote:
Originally Posted by qcpp View Post
when is it necessary ?
It's never necessary ! I mean there's nothing that cannot be done without forward declaration.

Quote:
Originally Posted by qcpp View Post
is there any specific conditions ?
Yes, there are. When you forward declare, the compiler has no idea about the contents of the class, it just knows that a class exists. So, you cannot use forward declaration for a class, when you want to access the members of that class.

Some examples, for further clarification. When you forward declare a class A, you can do things like:
  • Declaring a reference or pointer to it.
  • Declaring a func, whose arg type or return type is that class.
  • Declaring a func, whose arg type or return type is pointer/reference to that class.
But you cannot:
  • Declare a member of that type.
  • Use it as base class.
  • Define func, whose return/arg-type is that class.
  • De-reference a pointer of the forward declared class.
Quote:
Originally Posted by qcpp View Post
Thanks in Advance..
You are welcome !
0
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
> there's nothing that cannot be done without forward declaration

Yes there is.
Code:
class A {
  B *b_ptr;
};

class B {
  A *a_ptr;
};
This is impossible without at least one forward reference. If A and B are in separate headers then #including each in the other will send the compiler into an infinite loop.

Solution:
Code:
class B; // forward reference

class A {
  B *b_ptr;
};

class B {
  A *a_ptr;
};
0
SaswatPadhi's Avatar, Join Date: May 2009
~ Б0ЯИ Τ0 С0δЭ ~
Quote:
Originally Posted by xpi0t0s View Post
Yes there is.


I would use #pragma once above every header file, instead of forward declaration (just to prove that it can be avoided )

Last edited by SaswatPadhi; 13May2009 at 17:20.. Reason: Nothing special :p
0
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
That's compiler specific (all #pragma's are). Forward declarations are portable.
0
SaswatPadhi's Avatar, Join Date: May 2009
~ Б0ЯИ Τ0 С0δЭ ~
Quote:
Originally Posted by xpi0t0s View Post
That's compiler specific (all #pragma's are). Forward declarations are portable.
Though #pragma once is accepted by MOST compilers, that they are not portable. Well, I was just trying to point out a way to avoid forward declaration, it's not my enemy LOL.

So, we learn, there are somethings(Cyclic dependency) that can be resolved only by forward declaration.
0
qcpp's Avatar, Join Date: May 2009
Newbie Member
Wow.. !!! thanks a million for all those explanations..

but i have one more question.. because i have a situation here.. where even though i include .h file and if i try to compile the code without forward declaration , the compiler throws error saying ISO C++ forbids something (at the line where i use a A *test)
So, even though i include A.h why cant the compiler find that there is a class named A, What makes the compiler to throw error ?
0
SaswatPadhi's Avatar, Join Date: May 2009
~ Б0ЯИ Τ0 С0δЭ ~
If class A (in A.h) does not contain anything related to class B (in B.h), but only class B contains A *test, then including A.h in B.h should work. :

If it does not, please post the contents of A.h and B.h and the details of the error.
0
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
Post the exact error please, not a vague interpretation of what you think it might say.