6 Replies - 1301 Views - Last Post: 16 June 2010 - 08:51 AM Rate Topic: -----

#1 bear(NP)  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 144
  • Joined: 18-February 09

Multiple Inclusion?

Posted 16 June 2010 - 07:12 AM

Hey guys, I'm trying to write a simple game where a player class is stored in a separate .cpp file. However, I get this error when I try to compile:

Quote

1>playerClass.obj : error LNK2005: "public: __thiscall Player::Player(int,int,int,int)" (??0Player@@QAE@HHHH@Z) already defined in mainGameLoop.obj
1>playerClass.obj : error LNK2005: "private: void __thiscall Player::move(int)" (?move@Player@@AAEXH@Z) already defined in mainGameLoop.obj
1>playerClass.obj : error LNK2005: "public: void __thiscall Player::update(void)" (?update@Player@@QAEXXZ) already defined in mainGameLoop.obj


Can anybody help me out? Or better yet, better explain this error?

Here's the playerClass.cpp file:
#include "SDLFiles.h"

class Player{
	//&&&images, CD, etc.

	private:
		int distance; //distance moved per movement
		int speed; //time the timeres have to reach or surpass to move
		int timerUp, timerDown, timerRight, timerLeft; //used to prevent quick movement (coords in int) 
		void move(int direction); //move the player according to the direction given

	public:
		Player(int x, int y, int w, int h); //constructor
		SDL_Rect box; //used to store attributes of player
		void update();
};
Player::Player(int x, int y, int w, int h){
	//player attributes stored in a box
	box.x = x;
	box.y = y;
	box.w = w;
	box.h = h;

	//movement variables
	speed = 20;
	distance = 1;
	timerUp = 0;
	timerDown = 0;
	timerRight = 0;
	timerLeft = 0;
}

void Player::move(int direction){
	//moves the player accordint to the direction given
	//1 = up, 2 = right, 3 = down, 4 = left
	//if the player wants to move a direction, and the timer is satisfied...
	if((direction == 1) && (timerUp >= speed)){
		box.y -= distance;
		timerUp = 0;
	}
	if((direction == 2) && (timerRight >= speed)){
		box.x += distance;
		timerRight = 0;
	}
	if((direction == 3) && (timerDown >= speed)){
		box.y += distance;
		timerDown = 0;
	}
	if((direction == 4) && (timerLeft >= speed)){
		box.x -= distance;
		timerLeft = 0;
	}
}

void Player::update(){
	//updates the player's key states and timers
	timerLeft++;
	timerRight++;
	timerUp++;
	timerDown++;

	Uint8 *keystates = SDL_GetKeyState(NULL); //creates an array of key states (pressed/not)
	if(keystates[SDLK_UP]){
		//if the up key is pressed...
		move(1);
	}
	if(keystates[SDLK_RIGHT]){
		//if the right key is pressed...
		move(2);
	}
	if(keystates[SDLK_DOWN]){
		//if the down key is pressed...
		move(3);
	}
	if(keystates[SDLK_LEFT]){
		//if the left key is pressed...
		move(4);
	}
	//delete keystates;
}



and the mainGameLoop.cpp file:

//include files
#include "mainHeader.h" //the header for this file

//window attributes
const int SCREEN_WIDTH = 500;
const int SCREEN_HEIGHT = 500;
const int SCREEN_BPP = 32; //32bit coloring

//create the player object
//Player dude(50, 50, 50, 50);

//event variable for handling X-ing of window
SDL_Event event;

//the surfaces; used for displaying images
SDL_Surface *screen = NULL; //the entire window
SDL_Surface *playerimg = NULL; //image of player
SDL_Surface *ground = NULL; //ground below player

SDL_Surface *load_image(std::string filename){
	//loads individual images

	//image that's loaded
	SDL_Surface* loadedImage = NULL;

	//optimized surface that will be used
	SDL_Surface* optimizedImage = NULL;

	if(loadedImage != NULL){
		//if image loaded properly...

		//create an optimized surface
		optimizedImage = SDL_DisplayFormat(loadedImage);

		//free old surface
		SDL_FreeSurface(loadedImage);

		if(optimizedImage != NULL){
			//if image optimized...
			//do nothing for now
		}
	}
	return optimizedImage;
}

void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL){
	//display a surface on the screen surface

	//hold offsets
	SDL_Rect offset;
	offset.x = x;
	offset.y = y;

	//"Blit"; apply the surface to the screen (surface)
	SDL_BlitSurface(source, clip, destination, &offset);
}

bool init(){
	//initiate the required resources

	if(SDL_Init(SDL_INIT_EVERYTHING) == -1){
		//if there was a problem
		return false;
	}

	//set up the screen
	screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
	
	if(screen == NULL){
		//if there was an error...
		return false;
	}

	//set window caption
	SDL_WM_SetCaption("Scap_Metal", NULL);

	//if everything is OK...
	return true;
}

bool load_files(){
	//access required files &&&add all image files
	playerimg = load_image("player.png");
	ground = load_image("ground.png");

	//image error checking
	if(playerimg == NULL){
		//if error with player image...
		return false;
	}
	if(ground == NULL){
		//if error with ground image...
		return false;
	}

	//if all images loaded OK...
	return true;
}

void clean_up(){
	//free all images and prep for stopExe

	//free surfaces
	SDL_FreeSurface(ground);
	SDL_FreeSurface(playerimg);

	//Quit SDL
	SDL_Quit();
}

int main(int argc, char* args[]){
	//houses main game loop, &&&player class

	//call prep functions
		//if there's an error, return 0
	if(init() == false){
		return 0;
	}
	if(load_files() == false){
		return 0;
	}

	//init variables
	bool quit = false; //used for quitting out of game loop

	while(quit == false){
		//main game loop
		while(SDL_PollEvent(&event)){
			//while there are events to handle...
			if(event.type == SDL_QUIT){
				//if the user Xs out, quit
				quit = true;
			}
		}
		//dude.update();

		//apply images
		apply_surface(0, 0, ground, screen); //draw the ground MUST BE FIRST
		//apply_surface(dude.box.x, dude.box.y, playerimg, screen); //draw the player

		//update screen
		if(SDL_Flip(screen) == -1){
			//if there is an error in updating, quit
			return 0;
		}
	}

	//clean up SDL and quit
	clean_up();
	return 1;
}



And the header files, mainHeader.h:
//protect against multi-inclusion
#ifndef MAINHEADER_H_
#define MAINHEADER_H_

//include files
#include "SDLFiles.h"

//function declerations

//classes
#include "playerClass.cpp"

#endif /* MAINHEADER_H_ */



and SDLFiles.h:
//protect against multi-inclusion
#ifndef SDLFILES_H_
#define SDLFILES_H_

//include files
	//SDL
#include "SDL.h"
#include "SDL_image.h"
	//file streaming
#include <fstream>

#endif /* SDLFILES_H_ */



Sorry for all the code, but I really have no idea what's going on here. My best guess is that, since there's no obvious multi-inclusion of the three methods, that the compiler is misinterpreting the error- but that sounds cocky, most likely I'm just an idiot.


Any help would be much appreciated.

Is This A Good Question/Topic? 0
  • +

Replies To: Multiple Inclusion?

#2 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6078
  • View blog
  • Posts: 23,546
  • Joined: 23-August 08

Re: Multiple Inclusion?

Posted 16 June 2010 - 07:36 AM

//classes
#include "playerClass.cpp"



NEVER include a C or C++ file.
Was This Post Helpful? 1
  • +
  • -

#3 Banfa  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 83
  • View blog
  • Posts: 109
  • Joined: 07-June 10

Re: Multiple Inclusion?

Posted 16 June 2010 - 07:40 AM

Specifically split playerClass.cpp in 2, take

class Player{
...
};



And put it in a header, then include that header where you have included playerClass.cpp and also into playerClass.cpp.

Compile both cpp files and linker them together.
Was This Post Helpful? 0
  • +
  • -

#4 bear(NP)  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 144
  • Joined: 18-February 09

Re: Multiple Inclusion?

Posted 16 June 2010 - 07:46 AM

Answered my own question: Shouldn't have included .cpp file, should only do class definition in a header file

EDIT:
Sorry, I didn't see you guys had posted. Thanks for the help anyways

This post has been edited by bear(NP): 16 June 2010 - 07:48 AM

Was This Post Helpful? 0
  • +
  • -

#5 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: Multiple Inclusion?

Posted 16 June 2010 - 08:32 AM

View PostJackOfAllTrades, on 16 June 2010 - 09:36 AM, said:

//classes
#include "playerClass.cpp"



NEVER include a C or C++ file.


Well I might not say NEVER -- just make sure you know what you are doing. Though when I DO include code snippets generally I name them .inc rather than .c or .cpp since generally the idea is that they would not be compiled/linked separately.

I think the important thing here is to understand what #include does -- it takes the contents of the file and PASTES it into the code... So lets imagine what happens when you #include a source code file.

First off, you IDE probably compiles playerClass.cpp and sends playerClass.obj to the linker when it builds other files (though I think most IDE's use the .h files to determine dependencies... never really thought too much about it). So already you have a problem because anything defined in playerClass.cpp will exit in the linkers symbol table from the .cpp file.

Then you compile mainGameLoop.cpp which includes mainHeader.h which includes playerClass.cpp -- no problem for the compiler, it generates a mainGameLoop.obj -- but when the linker goes to link mainGameLoop.obj and playerClass.obj it has a problem -- the SAME symbols are defined, it does not know which ones to use it spits out an error about multiple definitions.

Lets say you specifically remove playerClass.obj from the picture somehow (editing your IDE's build properties) and so things are great again... then you create additional.cpp file and you #include mainHeader.h which includes playerClass.cpp and so the compiler generates additional.obj and when the linker gets additional.obj and mainGameLoop.obj it sees duplicate definitions AGAIN.

So as a RULE OF THUMB:

Quote

NEVER include a C or C++ file.
IF you decide to break the rule -- ensure that you know what you are doing!!! I would say: NEVER include a .cpp or .c file -- if you must, then DON'T include it in a header file or any file that will be included in multiple source files.


for now... just stick to what Jack said.
Was This Post Helpful? 1
  • +
  • -

#6 Banfa  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 83
  • View blog
  • Posts: 109
  • Joined: 07-June 10

Re: Multiple Inclusion?

Posted 16 June 2010 - 08:37 AM

I saying we use in the theater (but that I think applies to programming) is:

It is OK the break the rules, but you should know what they are before you break them

Was This Post Helpful? 2
  • +
  • -

#7 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: Multiple Inclusion?

Posted 16 June 2010 - 08:51 AM

+1 Banfa -- actually I should probably not have posted that. I got a little indignant about the whole "NEVER" bit. but Jack really did give the best advice for a beginner, I probably just added more confusion to the discussion.

I never have never really grasped "brevity"
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1