Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Trouble with multiple classes and header files
Index -> Programming, C++ -> C++ Help
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
HyperFlexed




PostPosted: Sun Jun 20, 2010 3:09 pm   Post subject: Trouble with multiple classes and header files

disclaimer: very new with C++. A lot of it still warps my mind. Anywho, I have 2 classes I'm working on for a game, Entity (base class for all the objects in the game), and SpriteSheet (a simple representation of all the sprites for my game).

Entity.h
c++:
#include "SpriteSheet.h"

class Entity {
        private:
                int x, y, xSpd, ySpd, xAcc, yAcc;
                SpriteSheet sprites;
       
        public:
                // Constructor
                Entity(int x = 0, int y = 0, int xSpd = 0, int ySpd = 0, int xAcc = 0, int yAcc = 0, SpriteSheet sprites);
               
                // Destructor
                ~Entity ();
               
                // Set co-ordinates on screen
                void setX(int x);       
                void setY(int y);
               
                // Set speed
                void setXSpd(int xSpd);
                void setYSpd(int ySpd);
               
                // Set acceleration
                void setXAcc(int xAcc);
                void setYAcc(int yAcc);
               
                // Get x and y co-ordinates
                int getX();
                int getY();
               
                // Get x and y speed
                int getXSpd()
                int getYSpd();
               
                // Get x and y acceleration
                int getXAcc()
                int getYAcc();
};


Entity.cpp
c++:
#include "SpriteSheet.h"

class Entity {
        private:
                int x, y, xSpd, ySpd, xAcc, yAcc;
                SpriteSheet sprites;
       
        public:
                // Constructor
                Entity(int x, int y, int xSpd, int ySpd, int xAcc, int yAcc, SpriteSheet sprites){
                        this->x = x;
                        this->y = y;
                        this->xSpd = xSpd;
                        this->ySpd = ySpd;
                        this->xAcc = xAcc;
                        this->yAcc = yAcc;
                        this->sprites = sprites;
                }
               
                // Destructor
                ~Entity (){
                        delete &x;
                        delete &y;
                        delete &xSpd;
                        delete &ySpd;
                        delete &xAcc;
                        delete &yAcc;
                        delete &sprites;
                }
               
                // Set co-ordinates on screen
                void setX(int x){this->x = x;} 
                void setY(int y){this->y = y;}
               
                // Set speed
                void setXSpd(int xAcc){this->xSpd = xAcc;}     
                void setYSpd(int yAcc){this->ySpd = yAcc;}
               
                // Set acceleration
                void setXAcc(int xAcc){this->xAcc = xAcc;}     
                void setYAcc(int yAcc){this->yAcc = yAcc;}
               
                // Get x and y co-ordinates
                int getX(){return x;}   
                int getY(){return y;}
               
                // Get x and y speed
                int getXSpd(){return xSpd;}     
                int getYSpd(){return ySpd;}
               
                // Get x and y acceleration
                int getXAcc(){return xAcc;}     
                int getYAcc(){return yAcc;}
};


SpriteSheet.h
c++:
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"

class SpriteSheet{
        private:
                SDL_Surface *spritesheet;
                SDL_Rect *clipArray;
       
        public:
                SpriteSheet(int numStates, int numAnimationStates, SDL_Surface *spritesheet, SDL_Rect *clipArray);
};


SpriteSheet.cpp
c++:
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"

class SpriteSheet{
        private:
                SDL_Surface *spritesheet;
                SDL_Rect *clipArray;
       
        public:
                SpriteSheet(int numStates, int numAnimationStates, SDL_Surface *spritesheet, SDL_Rect *clipArray){
                        // do stuff
                }
};


SpriteSheet is a bit sparse at the moment. I'll fill it in later. The issue is that when I try to compile Entity.cpp I get the following error:

code:
johnny@picard:~/coding/shmupGame$ g++ Entity.cpp
Entity.cpp: In constructor ?Entity::Entity(int, int, int, int, int, int, SpriteSheet)?:
Entity.cpp:10: error: no matching function for call to ?SpriteSheet::SpriteSheet()?
SpriteSheet.h:10: note: candidates are: SpriteSheet::SpriteSheet(int, int, SDL_Surface*, SDL_Rect*)
SpriteSheet.h:4: note:                 SpriteSheet::SpriteSheet(const SpriteSheet&)


As far as I can tell the SpriteSheet class has its constructor there plain as day. Any idea why my program is choking?
Sponsor
Sponsor
Sponsor
sponsor
TerranceN




PostPosted: Sun Jun 20, 2010 3:35 pm   Post subject: Re: Trouble with multiple classes and header files

You are implementing the class methods wrong.

For example lets say I have a class that has a number, a constructor, a getter and setter:

SomeClass.h
c++:
class SomeClass
{
    int number;
   
public:
    SomeClass(int newNumber);

    int GetNumber();
    void SetNumber(int newNumber);
};


SomeClass.cpp
c++:
#include "SomeClass.h"

SomeClass::SomeClass(int newNumber)
{
    number = newNumber;
}

int SomeClass::GetNumber()
{
    return number;
}

void SomeClass::SetNumber(int newNumber)
{
    number = newNumber;
}


You can also implement the functions when you declare them in your header file (exactly like you have in your .cpp files right now)

Hope that helps.
HyperFlexed




PostPosted: Sun Jun 20, 2010 4:14 pm   Post subject: Re: Trouble with multiple classes and header files

so what you're saying is in a header file you use the class construct, but in the actual cpp file you use the :: operator instead? Any reason for why its done this way?

Also, I notice that your member variable doesn't get declared in the .cpp file. The header takes care of this?

I fixed up my files as you had shown, and added some include guards (to mitigate the remaining errors). Works like a charm now. Are header guards the only viable way of preventing redefinition errors? I don't recall seeing so many of them in other programs.
HyperFlexed




PostPosted: Sun Jun 20, 2010 4:49 pm   Post subject: Re: Trouble with multiple classes and header files

Hmm, new one now.

I've created a main.cpp so I can test my objects

c++:
#include "Entity.h"
#include "SpriteSheet.h"

int main(int argc, char **argv){

        Entity *ship = new Entity(10,10,10,10,10,10,NULL);
        SpriteSheet *sheet = new SpriteSheet(10,10,NULL,NULL);

        return 0;

}


I try compiling:
code:
johnny@picard:~/coding/shmupGame$ g++ main.cpp -lSDL -lSDL_image
In file included from main.cpp:2:
SpriteSheet.h:7: error: redefinition of ?class SpriteSheet?
SpriteSheet.h:7: error: previous definition of ?class SpriteSheet?


So I look at SpriteSheet.h:
c++:
#ifndef SDL_HEADERS
#define SDL_HEADERS
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#endif

class SpriteSheet{
        private:
                SDL_Surface *spritesheet;
                SDL_Rect *clipArray;
       
        public:
                SpriteSheet(int numStates, int numAnimationStates, SDL_Surface *spritesheet, SDL_Rect *clipArray);
};


and I can't see a redefinition. However, I see that in main, Entity.h is included first, so maybe it's a problem with that file:

c++:
#ifndef SPRITESHEET_H
#define SPRITESHEET_H
#include "SpriteSheet.h"
#endif

class Entity {
        private:
                int x, y, xSpd, ySpd, xAcc, yAcc;
                SpriteSheet *sprites;
       
        public:
                // Constructor
                Entity(int x = 0, int y = 0, int xSpd = 0, int ySpd = 0, int xAcc = 0, int yAcc = 0, SpriteSheet *sprites = NULL);
               
                // Destructor
                ~Entity ();
               
                // Set co-ordinates on screen
                void setX(int x);       
                void setY(int y);
               
                // Set speed
                void setXSpd(int xSpd);
                void setYSpd(int ySpd);
               
                // Set acceleration
                void setXAcc(int xAcc);
                void setYAcc(int yAcc);
               
                // Get x and y co-ordinates
                int getX();
                int getY();
               
                // Get x and y speed
                int getXSpd()
                int getYSpd();
               
                // Get x and y acceleration
                int getXAcc()
                int getYAcc();
};


But it has an include guard, so I don't see how I'm getting a redefinition error.

Edit: I see now that since Entity.h includes SpriteSheet.h, I need an include guard in main.cpp (or I have to simply remove SpriteSheet's include). Now that I've done that, I get:

code:
johnny@picard:~/coding/shmupGame$ g++ main.cpp -lSDL -lSDL_image
/tmp/ccBRFi8P.o: In function `main':
main.cpp:(.text+0x53): undefined reference to `Entity::Entity(int, int, int, int, int, int, SpriteSheet*)'
main.cpp:(.text+0x84): undefined reference to `SpriteSheet::SpriteSheet(int, int, SDL_Surface*, SDL_Rect*)'
collect2: ld returned 1 exit status


and it looks like one of the most brutal errors I've ever seen. Strange references to tmp files. Random patches of hex digits. What's going on here?
TerranceN




PostPosted: Sun Jun 20, 2010 5:12 pm   Post subject: RE:Trouble with multiple classes and header files

Why you use the :: operator
Separating the definition and implementation of a class is just like using function prototypes. But because the function is in a class you need to say what class its in (cause multiple classes could have a method with the same name). You do this using the scope resolution operator, ::

variables in classes
Yes the header takes care of it (unless its static, I dont remember why) because you are just defining the variable, not implementing it (giving it a value)

header guards
Yes, header guards are the accepted way of preventing redefinitions, but your header guards are wrong.

The way it works is by checking if a macro is defined using #ifndef. If not then you know that source has not been compiled, so you define the macro with #define and place your source code after it. This way if anything else #include's your code it wont be recompiled. The problem you have is that your source code is outside that if statement so the if statement does nothing

The header guard should look like this:
c++:
#ifndef MACRONAME
#define MACRONAME
// your code here
#endif
HyperFlexed




PostPosted: Sun Jun 20, 2010 5:22 pm   Post subject: Re: RE:Trouble with multiple classes and header files

TerranceN @ Sun Jun 20, 2010 5:12 pm wrote:

header guards
Yes, header guards are the accepted way of preventing redefinitions, but your header guards are wrong.

The way it works is by checking if a macro is defined using #ifndef. If not then you know that source has not been compiled, so you define the macro with #define and place your source code after it. This way if anything else #include's your code it wont be recompiled. The problem you have is that your source code is outside that if statement so the if statement does nothing

The header guard should look like this:
c++:
#ifndef MACRONAME
#define MACRONAME
// your code here
#endif


I'm using ifndef to make sure headers aren't included multiple times. The error I have now though is:

code:
main.cpp:(.text+0x53): undefined reference to `Entity::Entity(int, int, int, int, int, int, SpriteSheet*)'
main.cpp:(.text+0x84): undefined reference to `SpriteSheet::SpriteSheet(int, int, SDL_Surface*, SDL_Rect*)'


I'm used to seeing this error when a function isn't defined, but I'm unsure as to how these functions haven't been defined. Is there any way I can see what g++ is looking at after all the preprocessor directives have been parsed? If I could do this, I would expect to see that main.cpp is missing definitions for the Entity and SpriteSheet constructors (based on the error above).

Also, what is the meaning of "main.cpp:(.text+0x84)"?

EDIT: I found the -E option (which outputs the preprocessed source). The result is here: http://pastebin.com/LQFFUAyq

The relevant code begins at line 4829

I can see that prototypes for my functions are there, but the full definitions are not. Do I have to somehow include Entity.cpp and SpriteSheet.cpp, or is this some kind of compiler flag?
HyperFlexed




PostPosted: Sun Jun 20, 2010 5:38 pm   Post subject: Re: Trouble with multiple classes and header files

K, I feel dumb.

Tried:
code:
g++ Entity.cpp SpriteSheet.cpp main.cpp -o main


And there was much rejoicing. Bits for your tolerance of my utter noobosity.
Display posts from previous:   
   Index -> Programming, C++ -> C++ Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 7 Posts ]
Jump to:   


Style:  
Search: