Reputation: 65951
I found this question When to use forward declaration? which is useful, but it is descriptive not prescriptive.
My scenario is typically I'm using a pointer to another class either as a class member or function argument so all I need in the header is a forward declaration (also as an aside, if I were to switch to using boost shared_ptr's would they be compatible with using forward declarations?). Currently I'm just including the headers but now I'm wondering if I should use forward declarations.
So my question is, if I can use a forward declaration for a class, should I? I'm hoping this question is not subjective, but if there is not a best practice answer then what are the pros/cons of using forward declarations?
UPDATE
Just to expand on the shared_ptr issue (I'm not using them now but considering the switch). If I were to use them I think I'd use the practice of typedef'ing the shared_ptr type inside the class. E.g.:
class Customer
{
public:
typedef std::tr1::shared_ptr<Customer> SharedPointer;
Customer() {}
virtual ~Customer() {}
virtual std::string GetName() const;
};
Seems like that might make things messier. Would that be problematic with forward declaration and if so is there a simple workaround?
Upvotes: 5
Views: 1617
Reputation: 28241
They usually say that you should use forward declarations wherever possible. This rule, like all rules, has exceptions. For me, the exceptional cases are often when the type name is overly complicated (i.e. template), or when there are too many names. For example, the following is a forward declaration:
namespace foo
{
namespace bar
{
template <typename T1, typename T2, int X>
class MyNiftyType;
// Hmm, maybe declare more types here?
}
// Hmm, maybe declare even more types here?
}
If that stuff could be avoided by doing just #include "MyNiftyStuff.h"
, i'd better #include
!
BTW there is a standard header file <iosfwd>
that contains forward declarations for some stream types. It seems to be invented specifically so you are able to declare operator<<(std::ostream&, ...)
(it's my personal opinion, sorry if it's wrong after all).
Edit: regarding shared_ptr<type>
.
Roughly speaking, the only thing you can do with shared pointers (to forward-declared types) is declaring functions. If you want to define a function that does something useful with shared_ptr<type>
, you cannot just forward-declare type
. For example:
MyCode.h
class MyClass;
void DoMuchStuff(shared_ptr<MyClass> ptr); // declaration - OK
inline void DoDoubleStuff(shared_ptr<MyClass> ptr) // definition - not OK!
{
void DoMuchStuff(ptr);
void DoMuchStuff(ptr);
}
If i used a normal pointer instead of shared_ptr
, this would work with forward declarations. But this inconvenience rarely hits you - either you have just declarations in your .h
files, or your inline functions are sufficiently complex that you have to #include
the full declaration for your class anyway.
Upvotes: -1
Reputation: 11
I think its better to use forward declaration to improve compilation speed (not to include masssive files) for the question of using shared pointer it doesnt change anything as shared pointer is just a wrapper taking care of cleaning the heap memory
Upvotes: 1
Reputation: 124642
Yes, you should. Remember that anything you include in a header is also included when clients of your code use it. It is best to include only the minimum number of files needed in a header. Aside from that, if you don't need to include the entire file and a forward declaration is adequate it seems like a simple choice.
Upvotes: 1
Reputation: 20272
You might want to do that because including the files makes the compilation longer, but depending on how many cases you have and how big your code base is, it most likely won't be an issue.
Another thing to consider is the dependencies. You don't want to recompile all your code because of an include file that you changed, when all you need is just the pointer definition.
So my (subjective) answer would be Yes, you should.
Upvotes: 5