Header file order of inclusions. Is there a way around this?

Started by
18 comments, last by Chrono1081 14 years, 10 months ago
Quote:Original post by Chrono1081
Thank you guys for all the suggestions although I'll admit I am still really confused. No book/website I found has been able to explain how to split files well. I understand about the header and C++ files but admittedly completely shy away from them because they never seem to work right.


Try this.

It's not a beginner book, but it's based on real world examples and practices which rather than academic discussions. It's just a very broad topic which cannot be even touched by a tutorial or forum post.

The practices have changed to a degree, even when it comes to C++, but that book tackles a comprehensive range of issues both specific to C++, as well as general software design.

Also - years of experience. No way around it.

Advertisement
Are you sure it's not a problem of header dependency ?
Something like A.h includes B.h but B.h also includes A.h ...
If so, use forward declarations in .h files, and include the headers in .cpp files.
Thank you guys for all the replies. I apologize but I have not got to try any of them yet (I work 84 hour work weeks (no lie) and go to school online). I will be trying these suggestions today.

I know its something I am doing wrong but everything looks correct when I compare it to tutorials such as the gamedev tutorial and when I look at code examples it looks like I am doing the same thing but obviously not.

I learned the #ifndef from Netbeans of all places since it automatically puts them in your header files and have been using it since because its been working for me.

As for the book one poster mentioned that looks like the type of book I have been looking for and I will be ordering it.
I figure I'll mention this since it doesn't seem like anyone else has and it's best to learn it now before it bites you in the butt. According to the C++ Standard, identifiers beginning with an underscore followed by an upper case letter or beginning with two underscores are reserved for the implementation (meaning the compiler, not you). Include guards such as _PARENTCLASS_H break this rule and have the potential of conflicting with identifiers used by the compiler. I suggest removing the underscore from the beginning of your include guards... after all, are they really helping you at all?
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
Quote:Original post by Chrono1081
I know its something I am doing wrong but everything looks correct when I compare it to tutorials such as the gamedev tutorial and when I look at code examples it looks like I am doing the same thing but obviously not.

The article doesn't give an explicit example of how to handle class inheritance, but the rule there is the same as the rule for anything else - if you use something in a header, you must either forward declare it or #include it in the header. In this case you have to #include the ParentClass header from the ChildClass header. Each header should work on its own, not rely on its users (the .cpp files) pulling in any other headers that it requires. That's effectively the route you were taking with the idea of a 'library header' and it's usually a bad idea.
To give you a code example to apply this:

// This tells the compiler to only include this file once per compilation unit (cpp file)#pragma once// This file (Tree.h) defines a class called Tree which requires both std::vector and the leaf class// So we include the headers that defines those classes right here#include <vector>#include "Leaf.h"class Tree{    std::vector<Leaf> m_leafs};


No matter where you include this file (Tree.h), you will not need to include anything else.
I really appreciate everyones help but I am still stuck : / The worst part is I've done this before but for some reason I can not get it to work. Am I missing something somewhere?

I've stripped my SDL project of everything and just kept the absolute bare essentials to get a window and a background. (To keep things simple and to keep code to a minimum for posting.) Below are my files, there are three of them. main.cpp, Engine.h, Surfaces.h:

main.cpp
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <string>#include "SDL.h"#include "SDL_image/SDL_image.h"#include "Engine.h"SDL_Event event;int main(int argc, char *argv[]){	int done = 0;	Engine myGraphics;	Engine *graphics;	graphics = &myGraphics;			background = graphics->load_image("//Users//Admin1//Documents//TestGame//Images//background.png");	graphics->apply_surface(0,0, background, screen);		while ( !done ) 	{		/* Check for events */		while ( SDL_PollEvent(&event) )		{			switch (event.type) 			{				case SDL_MOUSEMOTION:					break;				case SDL_MOUSEBUTTONDOWN:					break;				case SDL_KEYDOWN:					/* Any keypress quits the app... */				case SDL_QUIT:					done = 1;					break;				default:					break;			}		}		SDL_Flip(screen);	}				/* Clean up the SDL library */	SDL_Quit();	return(0);}



Here is Engine.h
/* *  Engine.h *  TestGame * *  Created by Admin1 on 5/25/09. *  Copyright 2009 __MyCompanyName__. All rights reserved. * */#include "Surfaces.h"class Engine	{	public:		Engine();				//Loads images of any format		SDL_Surface *load_image(std::string filename);				//Apply the image to a surface		void apply_surface(int x, int y, SDL_Surface *source, SDL_Surface *destination, SDL_Rect *clip);			private:		int SCREEN_WIDTH;		int SCREEN_HEIGHT;		int SCREEN_BPP;				int initializeScreen();				};Engine::Engine(){	SCREEN_WIDTH  = 640;	SCREEN_HEIGHT = 480;	SCREEN_BPP    = 32;		initializeScreen();}int Engine::initializeScreen(){		//Initialize SDL Subsystems	if(SDL_Init(SDL_INIT_EVERYTHING) == -1)		return 1;		//Set the icon for the screen	SDL_WM_SetIcon(NULL, NULL);		//Set up the screen	screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);	if(screen == NULL)		return 1;		//Set the window caption	SDL_WM_SetCaption("Testing", NULL);		return 0;}SDL_Surface* Engine::load_image(std::string filename){	//The image that is loaded	SDL_Surface *loadedImage = NULL;		//The optimized image that will be used	SDL_Surface *optimizedImage = NULL;		//Load the image using SDL_image	loadedImage = IMG_Load(filename.c_str());		//If the image loaded	if(loadedImage != NULL)	{   		//Create optimized image		optimizedImage = SDL_DisplayFormat(loadedImage);				//Free the old image		SDL_FreeSurface(loadedImage);				if(optimizedImage != NULL)		{			//Map the color key			Uint32 colorkey = SDL_MapRGB(optimizedImage->format, 255,0,255); //bright pink						//Set all pixels of 255,0,255 to transparent			SDL_SetColorKey(optimizedImage, SDL_SRCCOLORKEY, colorkey);		}	}		//Return the optimized Image	return optimizedImage;}void Engine::apply_surface(int x, int y, SDL_Surface *source, SDL_Surface *destination, SDL_Rect *clip = NULL){	//Holds offsets	SDL_Rect offset;		//Get offsets	offset.x = x;	offset.y = y;		//Blit	SDL_BlitSurface(source, clip, destination, &offset);}



Here is Surfaces.h
//SurfacesSDL_Surface *screen     = NULL;SDL_Surface *background = NULL;



All I really am after is to split the Engine header file into a header and a source file and I forget how : / Any help would be greatly appreciated.

[Edited by - Chrono1081 on May 25, 2009 11:11:55 AM]
Read the comments in the sources for explanation:

// main.cpp// you might want to double-check which of these headers you really need:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <string>#include "SDL.h"#include "SDL_image/SDL_image.h"#include "Engine.h"int main(int argc, char *argv[]){	int done = 0;        // um, why would you need both the instance AND a pointer to it?	Engine myGraphics;	// Engine *graphics;	// graphics = &myGraphics;		// I don't see any reason to make these global, so I moved them here:  SDL_Surface *screen     = NULL;  SDL_Surface *background = NULL;		background = graphics.load_image("//Users//Admin1//Documents//TestGame//Images//background.png");	graphics.apply_surface(0,0, background, screen);		while ( !done ) 	{		/* Check for events */		                // no need for this to be global, also it's good practice to declare		// variables as close to their use as possible		SDL_Event event; 		while ( SDL_PollEvent(&event) )		{			switch (event.type) 			{				case SDL_MOUSEMOTION:					break;				case SDL_MOUSEBUTTONDOWN:					break;				case SDL_KEYDOWN:					/* Any keypress quits the app... */				case SDL_QUIT:					done = 1;					break;				default:					break;			}		}		SDL_Flip(screen);	}				/* Clean up the SDL library */	SDL_Quit();	return(0);}
Oops forgot to delete those extra header files. They appear automatically whenever you launch an SDL template in XCode.


As for the pointer I was wondering that myself. I saw it in a book I have and decided not to question so I just copied it.

I'm still trying to wrap my head around SDL. Its really hard to find any resources on it besides the lazyfoo tutorials and Focus on SDL really doesn't do much for me. I was hoping the book had more practical examples : /

This topic is closed to new replies.

Advertisement