Sign in to follow this  
Soaps79

Seeking information on #include's

Recommended Posts

Soaps79    116
I am working on my first larger-scale project, and running into a lot of errors that I think are due to my lack of knowledge on #includes.

I thought I had the gist of it, but now I'm running into errors like "no default constructor" when I'm looking right at the one I created. Working in my own namespace is only compounding the problem. It may not be because of improper #includes, but my solution to the dependencies feels very duct-taped and I'd like to learn more about it. What I am looking for is a guide on when to #include in headers, when in .cpp's, when to just forward declare, etc.

Any recommendations?

Share this post


Link to post
Share on other sites
jpetrie    13106
Give this a read. Although it sounds like your errors may not all be directly related to header file management -- if you don't get your issues resolved after reading that article, post your code and errors.

Share this post


Link to post
Share on other sites
Buckeye    10747
Big projects can get pretty convoluted.

With regard to your question, the idea is, in general, to minimize dependencies by including in files only what is needed to compile that file.

If you have a header file that only needs to know that the someClass label is a class, use a forward declaration - e.g., you have only a std::vector<someClass*> in that header that needs to "know" anything about someClass. Using forward declarations in that way will minimize compile-time tasks.

The same general advice goes for source code files. If all that particular file needs to compile is a forward declaration, avoid adding an #include for the entire class.

Share this post


Link to post
Share on other sites
Quasimojo    279
Thanks for that link, jpetrie. I was having a problem with cyclic dependencies, myself. However, I think my problem can be solved by header file management, as you suggested - splitting code files unnecessarily, perhaps.

Share this post


Link to post
Share on other sites
Soaps79    116
Thanks for the info guys. Jpetrie, I had bookmarked that page months ago and forgotten all about it, thanks for the heads up. My #includes might not be perfect, but they don't seem to break any guidelines from that doc. Maybe someone can see the problem here:

Class TestClass is inheriting from class Entity, and has a Sprite* that will be newed in its constructor.

TestClass.h
#include "Entity.h"

#ifndef TESTCLASS_H
#define TESTCLASS_H

class Sprite;

class TestClass : public DDT::Entity
{
private:

Sprite* m_sprite;

public:

TestClass();
~TestClass();

virtual void Update();
virtual void Animate();
virtual void Draw();
};

#endif // TESTCLASS_H


from TestClass.cpp
#include "TestClass.h"
#include "Sprite.h"

TestClass::TestClass()
{
m_sprite = new Sprite();
}


from Sprite.h
#ifndef SPRITE_H
#define SPRITE_H

namespace DDT
{
class Sprite
{
private:

...

public:

Sprite();
~Sprite();
...
};
};


from Sprite.cpp
#include "Sprite.h"

namespace DDT
{
Sprite::Sprite()
{
// all private variables set
}
}; // namespace DDT


I ellipses'd the variables, but I don't think it affects the problem. A lot of variables are declared in the header and set in the constructor. The problem is that I get:

Error 1 error C2512: 'Sprite' : no appropriate default constructor available c:\capstone\source\ddtengine\testclass.cpp 14

When the default constructor is right in front of me. Any ideas?

Share this post


Link to post
Share on other sites
rip-off    10976
You are trying to call a constructor of an incomplete class ::Sprite. That is, the Sprite class in the global namespace (there is no such class).

Move your forward declaration into namespace DDT.

Note that #includes are generally kept inside the include guards. Not doing so will increase your build times.

Share this post


Link to post
Share on other sites
Soaps79    116
Please allow me to quote... me.

Quote:
Original post by Soaps79
Working in my own namespace is only compounding the problem.


Thanks a lot rip-off. All I did was add the DDT:: before Sprite and it's working out. The #include being outside of the guards was a (ghetto) workaround for bad dependencies I had going on previously, which has been remedied since reading the guide posted earlier.

Being the first time doing all of this, there's been a lot of frustration leading to "duh" moments, but hopefully go-to solutions if I run across the same mistakes in the future.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this