   c++ class and header include questions
  I have completed a few games using C++ and SDL but for each game I have only used 1 main file (and no classes, just structs and functions) for all my code.  For this next game, I am hoping to split it up using classes and header files.  But i'm having some problems.  I have a player class split into 2 files, player.h and player.cpp.  Right now I get a compile error in the header file saying the following:'string': is not a member of 'std'Different question:  I refer to an array of tiles in my player::checkwallcollisions function but that array is declared outside of the function and class.  Would I have to pass in that array and how would I go about doing that in my parameter list?Here is the player.h file:#ifndef PLAYER_H#define PLAYER_H#ifdef WIN32#pragma comment(lib, "SDL.lib")#pragma comment(lib, "SDLmain.lib")#pragma comment(lib, "SDL_TTF.lib")#endifclass Player{public:SDL_Surface surPlayerImage; //surface for player imagestd::string name; //hero nameint posx;  //x position of left cornerint posy;  //y position of left cornerint posx_middle;  //x position of middle of tileint posy_middle;  //y position of middle of tileint half_width;   //half of width of tileint half_height;  //half of height of tileint width;  //width of tileint height;  //height of tileint tilex;  //current x tile that player is inint tiley;  //current y tile that player is inbool moving_up;   //is hero moving upbool moving_down;  //is hero moving downbool moving_left;  //is hero moving leftbool moving_right; //is hero moving rightPlayer();void move();bool checkWallCollisions(Direction dir);};#endifHere is my player.ccp file:#include <stdlib.h>#include <cstdlib>#include <string.h>#include "SDL.h"#include "defines.h"#include "player.h"using namespace std;//Constructor for Player ClassPlayer::Player(){//set player namename = "Hero";//load player graphicsurPlayerImage = SDL_LoadBMP("Data/hero.bmp");moving_up = false;moving_down = false;moving_left = false;moving_right = false;}//Move hero 1 tile at a time in direction specifiedvoid Player::move(){if(moving_up){//check to see if hero is hitting wall or going off mapif(checkWallCollisions(UP) == false){posy = posy - PLAYER_SPEED;//the +8 below represents the map offset (which is 120)//and the nearest starting pos for y tile (which is 128)if((posy + 8) % TILE_SIZE == 0){moving_up = false;}}else{//stop playermoving_up = false;}}if(moving_down){//check to see if hero is hitting wall or going off mapif(checkWallCollisions(DOWN) == false){posy = posy + PLAYER_SPEED;//the +8 below represents the map offset (which is 120)//and the nearest starting pos for y tile (which is 128)if((posy + 8) % TILE_SIZE == 0){moving_down = false;}}else{//stop playermoving_down = false;}}if(moving_left){//check to see if hero is hitting wall or going off mapif(checkWallCollisions(LEFT) == false){posx = posx - PLAYER_SPEED;if(posx % TILE_SIZE == 0){moving_left = false;}}else{//stop playermoving_left = false;}}if(moving_right){//check to see if hero is hitting wall or going off mapif(checkWallCollisions(RIGHT) == false){posx = posx + PLAYER_SPEED;if(posx % TILE_SIZE == 0){moving_right = false;}}else{//stop playermoving_right = false;}}//update player variablesposx_middle = posx+(TILE_SIZE/2);posy_middle = posy+(TILE_SIZE/2);}bool Player::checkWallCollisions(Direction dir){int downY = 0;int upY = 0;int leftX = 0;int rightX = 0;bool upLeft = false;bool upRight = false;bool downLeft = false;bool downRight = false;int currentPosTopY = 0;int currentPosBottomY = 0;int currentPosRightX = 0;int currentPosLeftX = 0;switch(dir){case UP://first check to see if hero hits map edgeif(posy <= MAP_TOPY){return true;}//get 4 corners of player if he were to movecurrentPosRightX = posx_middle;currentPosLeftX = posx_middle;currentPosTopY = posy_middle - PLAYER_SPEED;currentPosBottomY = posy_middle - PLAYER_SPEED;break;case DOWN://first check to see if hero hits map edgeif(posy >= MAP_BOTTOMY){return true;}currentPosRightX = posx_middle;currentPosLeftX = posx_middle;currentPosTopY = posy_middle + PLAYER_SPEED;currentPosBottomY = posy_middle + PLAYER_SPEED;break;case LEFT://first check to see if hero hits map edgeif(posx <= MAP_LEFTX){return true;}currentPosRightX = posx_middle - PLAYER_SPEED;currentPosLeftX = posx_middle - PLAYER_SPEED;currentPosTopY = posy_middle;currentPosBottomY = posy_middle;break;case RIGHT://first check to see if hero hits map edgeif(posx >= MAP_RIGHTX){return true;}currentPosRightX = posx_middle + PLAYER_SPEED;currentPosLeftX = posx_middle + PLAYER_SPEED;currentPosTopY = posy_middle;currentPosBottomY = posy_middle;break;}downY = (currentPosBottomY+half_height-1-MAP_OFFSET)/TILE_SIZE;upY = (currentPosTopY-half_height-MAP_OFFSET)/TILE_SIZE;leftX = (currentPosLeftX-half_width)/TILE_SIZE;rightX = (currentPosRightX+half_width-1)/TILE_SIZE;//get either blocked or not blocked of the 4 tiles around pacmanupLeft = Map[upY][leftX].blocked;downLeft = Map[downY][leftX].blocked;upRight = Map[upY][rightX].blocked;downRight = Map[downY][rightX].blocked;switch(dir){case(UP)://check topright and topleft to see if pacman can move upif(upRight == false && upLeft == false){return false;}else{return true;}break;case(DOWN)://check topright and topleft to see if pacman can move upif(downRight == false && downLeft == false){return false;}else{return true;}break;case(LEFT)://check topright and topleft to see if pacman can move upif(upLeft == false && downLeft == false){return false;}else{return true;}break;case(RIGHT)://check topright and topleft to see if pacman can move upif(upRight == false && downRight == false){return false;}else{return true;}break;}return false;}Thanks,Han   
  For your first problem, you need to move #include <string> into your header file, above the class definition.For your second problem, you can pass arrays as pointers, like so:bool Player::checkWallCollisions(Direction dir, Tile *tiles, unsigned numtiles) {  for( unsigned i = 0; i < numtiles; ++i )    DoSomethingWithTile( tiles );}However, it would be better if you passed a reference to a vector (if you're using vectors):bool Player::checkWallCollisions(Direction dir, const std::vector< Tile > &tiles) {  for( unsigned i = 0; i < tiles.size(); ++i )    DoSomethingWithTile( tiles );}jfl.;  I think you'll have to include string.h in your header file#include <string>adding 'using namespace std;' wouldn't hurt either, but I don't think it's necessaryfor arrays as parameter, it's as simple asvoid MyClass::myFunction(int paramArray[]){ ...note that only the pointer on the first element of the array is copied as a parameterthat means that any changes made to the values in the array will be seen outside the function/methodthe size of the array is also unknown...you'll have to find a way around it, like passing the array size as a parameter tooEDIT : well, just like jflanglois said :)   ;Quote:Original post by SlashOwnsUadding 'using namespace std;' wouldn't hurt either, but I don't think it'sActually, it's best to not do that, so as to avoid namespace pollution.   ;Quote:Original post by Hannibal111111I have completed a few games using C++ and SDL but for each game I have only used 1 main file (and no classes, just structs and functions) for all my code.You have been one wise person, hope you don't try separating stuff into multiple files just for fun... Remember to keep some kind of tresshold in that LOC for division. It'd be good that you wouldn't divide in C++ unless you have over 1000 LOC in other files, it's a kind of good amount and with good documentation very clear approach. Otherwise you spend really too much time in writing include files, which really just makes you feel that you achieve something, better manage your code so that you have little include files compared to the code and not just feeling you achieving something... ;) You can try this at other stuff. Try read some online stuff, which you aren't familiar with, rich in links and references to other places and containing many pages. I don't know how do you feel, but for me it feels akward.Ok, to your second problem:Put #include <string.h> inside your player.h -definition, just before Player -class definition! I suspect that when you include this thing, you forget it somewhere along the system.Third:Array tiles is a kind of map, just pass the pointer to checkwallcollisions -function.This is how do you do it (assuming your map tile cells are type of int):checkwallcollisions(int map[]) { ... }you can call it this way:.checkwallcollisions(map); where map is an array of your tiles.   ;Quote:Original post by CheeryQuote:Original post by Hannibal111111I have completed a few games using C++ and SDL but for each game I have only used 1 main file (and no classes, just structs and functions) for all my code.You have been one wise person, hope you don't try separating stuff into multiple files just for fun... Remember to keep some kind of tresshold in that LOC for division. It'd be good that you wouldn't divide in C++ unless you have over 1000 LOC in other files, it's a kind of good amount and with good documentation very clear approach. Otherwise you spend really too much time in writing include files, which really just makes you feel that you achieve something, better manage your code so that you have little include files compared to the code and not just feeling you achieving something... ;) That's a terrible idea. You should be dividing your code logically, not based on a quota for lines of code. If you have a Player class that you want to reuse, should it be in its own header file, or should it be included with 800 other lines of code that have to do with the amount of fur on different species of cats?;  Hmm.  I have added #include <string.h> to my player.h file above the class declaration, but I still get the compile error.Here is my updated code for both player.h and player.cpp#ifndef PLAYER_H#define PLAYER_H#ifdef WIN32#pragma comment(lib, "SDL.lib")#pragma comment(lib, "SDLmain.lib")#pragma comment(lib, "SDL_TTF.lib")#endif#include <string.h>class Player{public:SDL_Surface surPlayerImage; //surface for player imagestd::string name; //hero nameint posx;  //x position of left cornerint posy;  //y position of left cornerint posx_middle;  //x position of middle of tileint posy_middle;  //y position of middle of tileint half_width;   //half of width of tileint half_height;  //half of height of tileint width;  //width of tileint height;  //height of tileint tilex;  //current x tile that player is inint tiley;  //current y tile that player is inbool moving_up;   //is hero moving upbool moving_down;  //is hero moving downbool moving_left;  //is hero moving leftbool moving_right; //is hero moving rightPlayer();void move();bool checkWallCollisions(Direction dir);};#endif#include <stdlib.h>#include <cstdlib>#include <string.h>#include "SDL.h"#include "defines.h"#include "player.h"using namespace std;//Constructor for Player ClassPlayer::Player(){//set player namename = "Hero";//load player graphicsurPlayerImage = SDL_LoadBMP("Data/hero.bmp");moving_up = false;moving_down = false;moving_left = false;moving_right = false;}//Move hero 1 tile at a time in direction specifiedvoid Player::move(){if(moving_up){//check to see if hero is hitting wall or going off mapif(checkWallCollisions(UP) == false){posy = posy - PLAYER_SPEED;//the +8 below represents the map offset (which is 120)//and the nearest starting pos for y tile (which is 128)if((posy + 8) % TILE_SIZE == 0){moving_up = false;}}else{//stop playermoving_up = false;}}if(moving_down){//check to see if hero is hitting wall or going off mapif(checkWallCollisions(DOWN) == false){posy = posy + PLAYER_SPEED;//the +8 below represents the map offset (which is 120)//and the nearest starting pos for y tile (which is 128)if((posy + 8) % TILE_SIZE == 0){moving_down = false;}}else{//stop playermoving_down = false;}}if(moving_left){//check to see if hero is hitting wall or going off mapif(checkWallCollisions(LEFT) == false){posx = posx - PLAYER_SPEED;if(posx % TILE_SIZE == 0){moving_left = false;}}else{//stop playermoving_left = false;}}if(moving_right){//check to see if hero is hitting wall or going off mapif(checkWallCollisions(RIGHT) == false){posx = posx + PLAYER_SPEED;if(posx % TILE_SIZE == 0){moving_right = false;}}else{//stop playermoving_right = false;}}//update player variablesposx_middle = posx+(TILE_SIZE/2);posy_middle = posy+(TILE_SIZE/2);}bool Player::checkWallCollisions(Direction dir){int downY = 0;int upY = 0;int leftX = 0;int rightX = 0;bool upLeft = false;bool upRight = false;bool downLeft = false;bool downRight = false;int currentPosTopY = 0;int currentPosBottomY = 0;int currentPosRightX = 0;int currentPosLeftX = 0;switch(dir){case UP://first check to see if hero hits map edgeif(posy <= MAP_TOPY){return true;}//get 4 corners of player if he were to movecurrentPosRightX = posx_middle;currentPosLeftX = posx_middle;currentPosTopY = posy_middle - PLAYER_SPEED;currentPosBottomY = posy_middle - PLAYER_SPEED;break;case DOWN://first check to see if hero hits map edgeif(posy >= MAP_BOTTOMY){return true;}currentPosRightX = posx_middle;currentPosLeftX = posx_middle;currentPosTopY = posy_middle + PLAYER_SPEED;currentPosBottomY = posy_middle + PLAYER_SPEED;break;case LEFT://first check to see if hero hits map edgeif(posx <= MAP_LEFTX){return true;}currentPosRightX = posx_middle - PLAYER_SPEED;currentPosLeftX = posx_middle - PLAYER_SPEED;currentPosTopY = posy_middle;currentPosBottomY = posy_middle;break;case RIGHT://first check to see if hero hits map edgeif(posx >= MAP_RIGHTX){return true;}currentPosRightX = posx_middle + PLAYER_SPEED;currentPosLeftX = posx_middle + PLAYER_SPEED;currentPosTopY = posy_middle;currentPosBottomY = posy_middle;break;}downY = (currentPosBottomY+half_height-1-MAP_OFFSET)/TILE_SIZE;upY = (currentPosTopY-half_height-MAP_OFFSET)/TILE_SIZE;leftX = (currentPosLeftX-half_width)/TILE_SIZE;rightX = (currentPosRightX+half_width-1)/TILE_SIZE;//get either blocked or not blocked of the 4 tiles around pacmanupLeft = Map[upY][leftX].blocked;downLeft = Map[downY][leftX].blocked;upRight = Map[upY][rightX].blocked;downRight = Map[downY][rightX].blocked;switch(dir){case(UP)://check topright and topleft to see if pacman can move upif(upRight == false && upLeft == false){return false;}else{return true;}break;case(DOWN)://check topright and topleft to see if pacman can move upif(downRight == false && downLeft == false){return false;}else{return true;}break;case(LEFT)://check topright and topleft to see if pacman can move upif(upLeft == false && downLeft == false){return false;}else{return true;}break;case(RIGHT)://check topright and topleft to see if pacman can move upif(upRight == false && downRight == false){return false;}else{return true;}break;}return false;};Quote:Original post by Hannibal111111Hmm.  I have added #include <string.h> to my player.h file above the class declaration, but I still get the compile error.Here is my updated code for both player.h and player.cpp*** Source Snippet Removed ***#include <string> != #include <string.h>string.h is considered deprecated, and you should only use string (no .h)The original string.h didn't use the std namespace, just the extentionless file does.  Many header files that were once in a .h counterpart now have an extentionless version wrapped into the std namespace.EDIT:I should have asked what error you were still getting.  This only pertains to the namespace error.  Sorry!  [grin]   ;  I find it surprising my suggestion didn't work.Quote:Original post by jflangloisThat's a terrible idea. You should be dividing your code logically, not based on a quota for lines of code. If you have a Player class that you want to reuse, should it be in its own header file, or should it be included with 800 other lines of code that have to do with the amount of fur on different species of cats?Depends how do you like it. I prefer having stuff in logical chunks, but not sacrifising too much extra writing to doing so. For example, you don't write ten lines long macro for two s-exprs in your code, even if it'd be sexy so. Neither you shouldn't do this kind of stuff in C++ (ok, C++ doesn't have semantic program enhancement logic, but it has another stuff which tries to help the coder...), even the language is very different the programming principles aren't changed.If you don't believe me with the argument, look at your header files and compare them to your sources (assuming you code like you prefer).   ;Quote:Original post by CheeryI find it surprising my suggestion didn't work.Depends how do you like it. I prefer having stuff in logical chunks, but not sacrifising too much extra writing to doing so. For example, you don't write ten lines long macro for two s-exprs in your code, even if it'd be sexy so. Neither you shouldn't do this kind of stuff in C++ (ok, C++ doesn't have semantic program enhancement logic, but it has another stuff which tries to help the coder...), even the language is very different the programming principles aren't changed.If you don't believe me with the argument, look at your header files and compare them to your sources (assuming you code like you prefer).Sure, I believe you with your argument, considering it is "depends on how you like it." If you're worried about extra writing in your header files, then you aren't putting the right things in your header files. You shouldn't be writing header files every five minutes, so it's not like you're writing much extra in the grand scheme of things.The idea of header files (and their associated implementation files) is that they encapsulate a particular logical unit. This allows easy code reusability as well as the side effect of not having to re-compile your entire project when you make a small change to unrelated code.jfl.   