Perfectly defined class comes up as undefined

Hello :D
I have a really REALLY weird problem that I am really frustrated by.
I am a novice programmer, and I decided to mess with some classes...
Anyway, long story short, I defined a bunch of classes, and one of the I made with inheritance from another one. but I get the errors(Edit 1):
graphic.h(3): error C2011: 'Graphic' : 'class' type redefinition
graphic.h(3) : see declaration of 'Graphic'
dot.h(5): error C2504: 'Graphic' : base class undefined

Now I checked every single line of code for a missing semicolon or a curly bracket (which from my earlier experience caused lots of similar problems) and apparently nothing is missing!
I checked the Classes tutorials on this website and it seems I am doing everything right...


Edit 1: added 2 more errors, and updated the code.


The files I use (Sorry for the huge amount, but its all the files I have so yeah):
##If you don't mind- Ignore the fact that this program won't work, I am aware of the fact. I was in the middle of turning everything to classes, so none of the classes are actually getting created during run time (if it will even get trough compiling any time soon...)##

Also I split the Headers in this post and CPPs on the next one, due to letter limit

main.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//Screen attributes
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

//The frame rate
const int FRAMES_PER_SECOND = 20;

//The dot dimensions
const int DOT_WIDTH = 20;
const int DOT_HEIGHT = 45;

//The dimensions of the level
const int LEVEL_WIDTH = 1280;
const int LEVEL_HEIGHT = 960;

//The camera
static SDL_Rect camera = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };


timer.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Timer
{
private:
	int startTicks;				//The clock time when the timer started
	int pausedTicks;			//The ticks stored when the timer was paused
	bool paused;
    bool started;

public:
	Timer();					//Initializes variables
	void start();
    void stop();
    void pause();
    void unpause();
    int get_ticks();			//Gets the timer's time
    bool is_started();
    bool is_paused();
};


graphic.h:
1
2
3
4
5
6
7
8
class Graphic
{
protected:
	SDL_Surface* image;
	void kill();
	void load_image(std::string filename);
	void apply_surface(int x, int y, SDL_Surface* destination, SDL_Rect* clip);
};


dot.h:(Edit 1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "SDL.h"
#include "graphic.h"


class Dot: public Graphic
{
private:
	int x, y;								//The X and Y offsets of the dot
    int xVel, yVel;							//The velocity of the dot
public:
	Dot();									//Initializes the variables
	void handle_input(SDL_Event &event);	//Takes key presses and adjusts the dot's velocity
	void move();							//Moves the dot
	void show();							//Shows the dot on the screen
	void set_camera();						//Sets the camera over the dot
};

Last edited on
main.cpp:
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
/*This source code copyrighted by Lazy Foo' Productions (2004-2011)
and may not be redestributed without written permission.*/

//The headers
#include "SDL.h"
#include "SDL_image.h"
#include <string>
#include "timer.h"
#include "graphic.h"
#include "dot.h"
#include "main.h"

//The surfaces
SDL_Surface *dot = NULL;
SDL_Surface *background = NULL;
SDL_Surface *screen = NULL;

//The event structure
SDL_Event event;

bool init()
{
    //Initialize all SDL subsystems
    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
    {
        return false;
    }

    //Set up the screen
    screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );

    //If there was an error in setting up the screen
    if( screen == NULL )
    {
        return false;
    }

    //Set the window caption
    SDL_WM_SetCaption( "Move the Dot", NULL );

    //If everything initialized fine
    return true;
}

int main( int argc, char* args[] )
{
    //Quit flag
    bool quit = false;

    //The dot
    Dot myDot;

    //The frame rate regulator
    Timer fps;

    //Initialize
    if( init() == false )
    {
        return 1;
    }

    //Load the files
    if( load_files() == false )
    {
        return 1;
    }

    //While the user hasn't quit
    while( quit == false )
    {
        //Start the frame timer
        fps.start();

        //While there's events to handle
        while( SDL_PollEvent( &event ) )
        {
            //Handle events for the dot
			myDot.handle_input(event);

            //If the user has Xed out the window
            if( event.type == SDL_QUIT )
            {
                //Quit the program
                quit = true;
            }
        }

        //Move the dot
        myDot.move();

        //Set the camera
        myDot.set_camera();

        //Show the background
        apply_surface( 0, 0, background, screen, &camera );

        //Show the dot on the screen
        myDot.show();

        //Update the screen
        if( SDL_Flip( screen ) == -1 )
        {
            return 1;
        }

        //Cap the frame rate
        if( fps.get_ticks() < 1000 / FRAMES_PER_SECOND )
        {
            SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() );
        }
    }

    //Clean up
	SDL_Quit();
    return 0;
}


timer.cpp:
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
#include "SDL.h"
#include "main.h"
#include "timer.h"

Timer::Timer()
{
    startTicks = 0;
    pausedTicks = 0;
    paused = false;
    started = false;
}

void Timer::start()
{
    started = true;					//Start the timer
	paused = false;					//Unpause the timer
	startTicks = SDL_GetTicks();	//Get the current clock time
}

void Timer::stop()
{
	started = false;				//Stop the timer
	paused = false;					//Unpause the timer
}

void Timer::pause()
{
    if((started == true) && (paused == false))			//If the timer is running and isn't already paused
	{
        paused = true;									//Pause the timer
        pausedTicks = SDL_GetTicks() - startTicks;		//Calculate the paused ticks
    }
}

void Timer::unpause()
{
    if( paused == true )								//If the timer is paused
    {
        paused = false;									//Unpause the timer
        startTicks = SDL_GetTicks() - pausedTicks;		//Reset the starting ticks
		pausedTicks = 0;								//Reset the paused ticks
    }
}

int Timer::get_ticks()
{
	if( started == true )								//If the timer is running
    {
        if( paused == true )							//If the timer is paused
        {
            return pausedTicks;							//Return the number of ticks when the timer was paused
        }
        else
        {
            return SDL_GetTicks() - startTicks;			//Return the current time minus the start time
        }
    }
    return 0;											//If the timer isn't running
}

bool Timer::is_started()
{
    return started;
}

bool Timer::is_paused()
{
    return paused;
}


graphic.cpp:
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
#include "SDL.h"
#include "SDL_image.h"
#include <string>
#include "graphic.h"

void Graphic::kill()
{
	SDL_FreeSurface(image);
}

void Graphic::load_image( std::string filename )
{
    image = IMG_Load(filename.c_str());	//The image that's loaded

    if(image != NULL)
    {
        image = SDL_DisplayFormat(image);
		SDL_SetColorKey(image, SDL_SRCCOLORKEY, SDL_MapRGB(image->format, 0, 0xFF, 0xFF));
    }
}

void Graphic::apply_surface(int x, int y, SDL_Surface* destination, SDL_Rect* clip = NULL)
{
    SDL_Rect offset;
    offset.x = x;
    offset.y = y;

    SDL_BlitSurface(image, clip, destination, &offset);
}


dot.cpp:
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
#include "dot.h"
#include "main.h"

Dot::Dot()
{
    x = 0;			//Initialize the offsets
    y = 0;
    xVel = 0;		//Initialize the velocity
    yVel = 0;
}

void Dot::handle_input(SDL_Event &event)
{
    //If a key was pressed
    if( event.type == SDL_KEYDOWN )
    {
        //Adjust the velocity
        switch( event.key.keysym.sym )
        {
            case SDLK_UP: yVel -= DOT_HEIGHT / 2; break;
            case SDLK_DOWN: yVel += DOT_HEIGHT / 2; break;
            case SDLK_LEFT: xVel -= DOT_WIDTH / 2; break;
            case SDLK_RIGHT: xVel += DOT_WIDTH / 2; break;
        }
    }
    //If a key was released
    else if( event.type == SDL_KEYUP )
    {
        //Adjust the velocity
        switch( event.key.keysym.sym )
        {
            case SDLK_UP: yVel += DOT_HEIGHT / 2; break;
            case SDLK_DOWN: yVel -= DOT_HEIGHT / 2; break;
            case SDLK_LEFT: xVel += DOT_WIDTH / 2; break;
            case SDLK_RIGHT: xVel -= DOT_WIDTH / 2; break;
        }
    }
}

void Dot::move()
{
    //Move the dot left or right
    x += xVel;

    //If the dot went too far to the left or right
    if( ( x < 0 ) || ( x + DOT_WIDTH > LEVEL_WIDTH ) )
    {
        //move back
        x -= xVel;
    }

    //Move the dot up or down
    y += yVel;

    //If the dot went too far up or down
    if( ( y < 0 ) || ( y + DOT_HEIGHT > LEVEL_HEIGHT ) )
    {
        //move back
        y -= yVel;
    }
}

void Dot::show()
{
    //Show the dot
    //apply_surface( x - camera.x, y - camera.y, dot, screen );
}

void Dot::set_camera()
{
    //Center the camera over the dot
    camera.x = ( x + DOT_WIDTH / 2 ) - SCREEN_WIDTH / 2;
    camera.y = ( y + DOT_HEIGHT / 2 ) - SCREEN_HEIGHT / 2;

    //Keep the camera in bounds.
    if( camera.x < 0 )
    {
        camera.x = 0;
    }
    if( camera.y < 0 )
    {
        camera.y = 0;
    }
    if( camera.x > LEVEL_WIDTH - camera.w )
    {
        camera.x = LEVEL_WIDTH - camera.w;
    }
    if( camera.y > LEVEL_HEIGHT - camera.h )
    {
        camera.y = LEVEL_HEIGHT - camera.h;
    }
}
Dot has no knowledge of Graphic, from what I can see in your code. In other words where is Graphic header in the Dot files? Make sure in each place you use something you have a matching header file.
Oh... someone once told me that including is almost the same as copying the same code instead.
And due to a few redefinition errors I once had, I was afraid of making them ever since, thanks for the tip :)

Back to my problem, I don't remember if it were before or not, but after I did what you told me, I noticed two more errors that accompany the previous one:
graphic.h(3): error C2011: 'Graphic' : 'class' type redefinition
graphic.h(3) : see declaration of 'Graphic'
dot.h(5): error C2504: 'Graphic' : base class undefined


I am updating the main posts with the new code.
Last edited on
I don't spot the actual problem, but I'm sure it has to do with your headers not being properly self contained.

I'm sure the problem will go away if you guard your headers and properly #include dependencies. Particularly, dot.h should be including graphic.h

See sections 3 and 4 of this article:
http://cplusplus.com/forum/articles/10627/#msg49679
Thanks a lot, I will read tommorow first thing in the morning [Its 3 AM here] :)
Hopefully this will help me with my code. Again- Thank you :)

EDIT: Disch you are amazing, you just helped me understand a huge thing and your article is really really helpful, thank you <3

Problem fixed by applying header guards :)
Last edited on
Topic archived. No new replies allowed.