Pre-Decaring None Pointer Members

I've read that you should not include header files in other header files and that you should instead pre-declare class members. I'm having trouble working out how to do this for non-pointer members. When the member is a pointer you can pre-declare it as follows:

1
2
3
4
5
6
class memberClass;

Class myClass
{
    memberClass* memberClassPtr;
};


However, if the member is not a pointer it doesn't work so the below code would produce a compilation error:

1
2
3
4
5
6
class memberClass;

Class myClass
{
    memberClass memberClassObj;
};


How do you pre-declare classes when the member isn't a pointer?

Also, how do yu pre-declare things like vectors to avoiding putting #include <vector> in the header file?

Thanks for any help you can offer.
I've read that you should not include header files in other header files and that you should instead pre-declare class members
That isn't true. If you need a header you can include it. The forward declaration are used so that you don't have circular includes.

You need to have memberClass to be defined before myClass. Forward declarations can be used for pointers and for methods
Thanks a lot for clearing that up for me. I thought I was doing something wrong by including headers in other header files but I couldn't see how t avoid it. It's good to know there's nothing wrong with doing it.

Thanks again.
Personally, I take the following approach in my code:

1) guard the header with #ifndef/#define to protect against multiple includes
2) If the header needs something fully defined, then #include the necessary header(s) right in your header
3) Anything that doesn't need to be fully defined can be forward declared in the header


The logic behind this is that:

- You can just #include a file once in your source and you have all the necessary dependencies, and will avoid a bunch of compiler errors. Example: If you have a source file that needs MyClass, then you can just #include "myclass.h" and don't have to remember to include "mysupportclass1.h", "mysupportclass2.h", etc, etc.
- If you change MyClass in the future and eliminate one of the dependencies, you can remove the dependency's #include from the header instead of having to remove it from the dozens or hundreds of other .cpp files that use MyClass
- Including a header twice doesn't hurt anything as long as the header is guarded with #ifndef. It might slow down compile time ever so slightly, but we're talking maybe 0.1 milliseconds. You could compile the program a million times and the extra time wasted by the includes would still be shorter than that one time you spent trying to remember which .h file you forgot.

Basically... make the header just work. Don't make your source have to figure out how to make the header work -- that just creates more work for yourself.



For example... say you have the following class defined in a header:

1
2
3
4
5
6
7
8
9
class Foo : public FooParent
{
public:
  void DoStuff();

protected:
  std::vector<int>  a;
  Bar*              b;
};


My recommendation for the header layout would be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef __FOO_INCLUDED__
#define __FOO_INCLUDED__

//-------------------------------------
//  dependencies:  stuff the class needs fully defined
#include <vector>
#include "fooparent.h"

//-------------------------------------
//  dependencies:  stuff that can be forward declared
class Bar;

//--------------------------------------
//  the actual class
class Foo : public FooParent
{
  //...
};

#endif // __FOO_INCLUDED__ 


Then if you have a source file that needs Foo, you can just #include "foo.h" and be done with it!

But of course this is all personal preference and style. Do it however you like. This is just what I recommend.
Last edited on
Thanks for the advice Disch. That's pretty much what I already do.

I was just trying to improve my programming a bit and having read in the past that including headers in headers "pollutes" other files I was worried I was doing something wrong but I feel a lot better now that I know it's not a problem.
Topic archived. No new replies allowed.