How Do I include some header so it does something more than declaring stuff?

How Do I include some header so it does something more than declaring stuff?

So basicly I have main class Game with include multiple other classes. More than one uses "Texture.h" header, but to that point I had it (Texture.h) in project, and everything worked fine since cpp file was in project.
Now I'm creating "my library" of headers, so I exported my Texture header to other directory. So here is my problem :
How can I make something else than declaring stuff... I can not just put cpp into header, because compiler will tell me about multiple definitions of Texture methods, but if I don't want that, I don't have anything defined.
Also I'm using include guards, but they doesn't work in that case AFAIK, because.. I'm getting error about multiple definitions


OLD VERSION (I had header in project together with cpp file, so there was no problem)

b.h
#include <a.h>

c.h
#include <a.h>

main.cpp
1
2
3
4
5
6
7
#include <b.h>
#include <c.h>
int main ()
{
    cls obj;
    obj.draw();
}


a.h
1
2
3
4
5
6
7
8
#ifndef a_h
#define a_h
class cls
{
    public:
    void draw();
}
#endif //a_h 


a.cpp
1
2
3
4
5
6
#include<a.h>

void cls::draw() 
{
    //some stuff
}

Last edited on
Hi,

It's not clear why you want to do this. It is definitely wrong to put cpp code into header files, unless it is template code.

One can organize the project into different sub-directories with related code in each one. I would do that, rather than have all the headers in one place.

With your header inclusions for your own header files, use quotes not <>, the rules are different, the quoted one will first look in the directory where the program is found - that's how a relative path can be made to work. If the include files are elsewhere, either specify the full path for the header file, or make sure you get the relative path correct. I like to use *.hpp for c++ header files.
Oh, I should write them in "" quotes.

Thanks for whole answer, my reason is I want to create header in my home directory, and use it in many projects without need to copy paste it everywhere, but I don't know how do do it right. All libraries define classes and functions and methods etc, but also make them do something. I just don't know how to make the "do" part without errors about multiple definitions. I know I should use cpp file for "THIS PART" but do I need to put it in project to make it compile? Libraries like SDL.h or iostream.h doesnt require me to include some stuff to project, yet they can do something and they can be included many times.
If I use include guards should that protect me if I include twice such code ? :

// not really refined, many things may be not ok, like now I'm thinking for what reason did I put there ttf... But thats just to show what I mean, not really a problem itself.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#ifndef texture_h
#define texture_h
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <string>
#include <vector>
#include <SDL2/SDL_ttf.h>
#include <iostream>

class Texture{
	public:
	    Texture ();
	    Texture ( std::string path, SDL_Renderer* gRenderer );
        ~Texture();
        bool loadFromFile( std::string path, SDL_Renderer* gRenderer );
        void free();
		void render( const SDL_Point* p, SDL_Rect* clip , SDL_Renderer* gRenderer );
		void render( SDL_Rect* r,  SDL_Rect* clip , SDL_Renderer* gRenderer );
		int getWidth();
		int getHeight();
		SDL_Texture* get_texture();
		void set_texture(SDL_Texture* texture, unsigned int w, unsigned int h);
		static void free_all();
		static std::string resources_path;
	private:
		SDL_Texture* mTexture;
		int mWidth;
		int mHeight;
        static std::vector <Texture*> textures;
};
// ========================= ! THIS PART is making me trouble. I want this header to DO something, not only declare things.
std::string Texture::resources_path;
Texture::Texture () : mTexture(NULL), mWidth(0), mHeight(0)
{
    textures.push_back(this);
}
//  !!! path load before renderer init ==> problems !!!
Texture::Texture ( std::string path, SDL_Renderer* gRenderer ): mTexture(NULL), mWidth(0), mHeight(0)
{
    textures.push_back(this);
    loadFromFile(path,gRenderer);
}
Texture::~Texture(){free();}
bool Texture::loadFromFile( std::string path, SDL_Renderer* gRenderer )
{
	free();

    #ifdef DEBUG
    printf ("loading texture : %s%s\n", resources_path.c_str(), path.c_str());
    #endif // DEBUG

	SDL_Texture* newTexture = NULL;

	SDL_Surface* loadedSurface = IMG_Load( ( resources_path+path ).c_str() );

	if( loadedSurface == NULL )
	{
		printf( "Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError() );
	}
	else
	{
	    // makes transparent pixel at this* color                                          *this
		// SDL_SetColorKey( loadedSurface, SDL_TRUE, SDL_MapRGB( loadedSurface->format, 0, 0xFF, 0xFF ) );

        newTexture = SDL_CreateTextureFromSurface( gRenderer, loadedSurface );

		if( newTexture == NULL )
		{
			printf( "Unable to create texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError() );
		}
		else
		{
			mWidth = loadedSurface->w;
			mHeight = loadedSurface->h;
		}

		SDL_FreeSurface( loadedSurface );
	}

	mTexture = newTexture;
	return mTexture != NULL;
}
void Texture::free()
{
    //Free texture if it exists
    if( mTexture != NULL )
    {
        SDL_DestroyTexture( mTexture );
        mTexture = NULL;
        mWidth = 0;
        mHeight = 0;
    }
}
void Texture::render( const SDL_Point* p, SDL_Rect* clip, SDL_Renderer* gRenderer )
{
    SDL_Rect renderQuad = { p->x, p->y, mWidth, mHeight };
	//Set clip rendering dimensions
	if( clip != NULL )
	{
		renderQuad.w = clip->w;
		renderQuad.h = clip->h;
	}

	//Render to screen
	SDL_RenderCopy( gRenderer, mTexture, clip, &renderQuad );

}
void Texture::render( SDL_Rect* r, SDL_Rect* clip, SDL_Renderer* gRenderer )
{
    SDL_Rect renderQuad = { r->x, r->y, r->w, r->h };
	//Set clip rendering dimensions
	if( clip != NULL )
	{
		renderQuad.w = clip->w;
		renderQuad.h = clip->h;
	}

	//Render to screen
	SDL_RenderCopy( gRenderer, mTexture, clip, &renderQuad );

}
int Texture::getWidth() {return mWidth;}
int Texture::getHeight() {return mHeight;}
void Texture::set_texture( SDL_Texture* tex, unsigned int w, unsigned int h)
{
    mTexture = tex;
    mWidth = w;
    mHeight = h;
}
SDL_Texture* Texture::get_texture(){return mTexture;}
void Texture::free_all()
{
    for (unsigned int i=0;i<textures.size();i++)
    {
        delete textures[i];
    }
    textures.clear();
}
std::vector <Texture*> Texture::textures;
// ========================= !  end THIS PART

#endif // texture_h
Last edited on
Ah, Ok it sounds like you want an actual library, not a collection of header files. There is where one compiles often used code, then other projects link against it in order to use it's functionality. There are two types: static (lib file on windows) and dynamic ( a dll file on windows). With the static one the whole thing is linked onto the project ; with the dynamic one, individual parts can be loaded - as opposed to loading the whole thing into memory.

You will have to look up how to do that, I haven't done it.

There are other options too:

One can make use of a pre-compiled header (often a *.pch file)

As mentioned earlier, one definitely cannot put cpp code into a header.
Libraries like SDL.h or iostream.h doesnt require me to include some stuff to project, yet they can do something and they can be included many times.


That's because one links against a library in order to use them. When you compile your SDL program, you have to link against an SDL library, although this is probbably buried in a make file.

Even if you didn't have libraries, just a regular c++ program, of course one can include your own header file in multiple places. The include guards prevent the declarations from appearing multiple times, and the header file has declarations only. The cpp file which a header file relates to must be compiled. Don't be scared of this, that is how it is normally done. The reason why you want a library here is for the reuse of the code which is a good thing.
Ok, that sounds a bit too complicated for me to be worth of solving it right now. I will just copy-paste my texture header with cpp back into project, but for sure I will make more experiments with pre-compiled headers and libraries. They look like good idea for bigger projects.
Thank you a lot!
Last edited on
I don't know anything about SDL, but it seems like dealing with textures is a common thing: is there no facility in the library for doing this? It seems a shame to have to roll your own code for that.
I will just copy-paste my texture header with cpp back into project, but for sure I will make more experiments with pre-compiled headers and libraries.


Just to be clear what I meant about sub-directories: You project should hopefully have a directory with the source code in it perhaps named src (as opposed to having everything code and executable's in 1 directory). It is underneath this directory that one creates new directories, so it is all still "in the project". If one moves or creates files to / in other locations the IDE must have a means of knowing where they are, so it can "make" the project automatically. Usually this is done while creating the class, there should be a menu option or toolbar button for that, it should open a Dialog box.
Just to be clear what I meant about sub-directories: You project should hopefully have a directory with the source code in it perhaps named src (...)

I add classes through C::B GUI, so it creates src and include folders and other things for me. Before that I was putting everything in 1 big "include" folder, but I'm learning every day.

I don't know anything about SDL, but it seems like dealing with textures is a common thing: is there no facility in the library for doing this? It seems a shame to have to roll your own code for that.

As far as I know it doesn't have that. I was learning basics from lazy foo and they write their own class for texture with every example. They know what they're doing I guess.

I think it's more convenient to create such class. Things you can do with texture in SDL are very limited, you can't even get size of it. But I like it. I know using raw SDL without help libraries and making everything by hand is like reinventing wheel, but I think it's some way to learn more by myself.
Last edited on
@OP: Append the FQPN to your PATH system variable with the location of the files you wish to include. This will prevent you from having to copy and paste copies of those header files into each individual project you create. This isn't an SDL or a C::B thing (although C::B does have a attribute you can set to accomplish this), your OS is also a tool that you are using to program.
Last edited on
Topic archived. No new replies allowed.