Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ undefined reference to static variable [duplicate]

I have no idea why this code isn't working. All the source files compile but when I try to link them the compiler yells at me with an undefined reference error. Here's the code:

main.cpp:

#include "SDL/SDL.h"
#include "Initilize.cpp"

int main(int argc, char* args[]) 
{
    //Keeps the program looping
    bool quit = false;
    SDL_Event exit;
    //Initilizes, checks for errors
    if(Initilize::Start() == -1) 
    {
        SDL_Quit();
    }
    //main program loop
    while(quit == false) 
    {
        //checks for events
        while(SDL_PollEvent(&exit)) 
        {
            //checks for type of event;
            switch(exit.type) 
            {
                case SDL_QUIT:
                quit = true;
                break;
            }
        }
    }
    return 0;
}

Initilize.h:

#ifndef INITILIZE_H
#define INITILIZE_H
#include "SDL/SDL.h"

/* Declares surface screen, its attributes, and Start(); */
class Initilize {
protected:
    static SDL_Surface* screen;
private:
    static int SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP;
public:
    static int Start();
};

#endif

Initilize.cpp:

#include "Initilize.h"
#include "SDL/SDL.h"

/* Initilizes SDL subsystems, sets the screen, and checks for errors */
int Initilize::Start() 
{
    //screen attributes
    SCREEN_WIDTH = 640;
    SCREEN_HEIGHT = 480;
    //Bits per pixel
    SCREEN_BPP = 32;
    //Inits all subsystems, if there's an error, return 1   
    if(SDL_Init(SDL_INIT_EVERYTHING) == -1) {
            return 1;
    }
    //sets screen
    screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
    //Returns 1 if there was in error with setting the screen
    if(screen == NULL) {
            return 1;
    }
    SDL_WM_SetCaption("Game", NULL);
    return 0;
}

Sorry if the code was formatted weirdly, inserting four spaces to put in a code block messed things up a little bit.

like image 338
user1602079 Avatar asked Aug 24 '12 23:08

user1602079


2 Answers

Add the following to your cpp file:

SDL_Surface* Initilize::screen = 0; // or nullptr
int Initilize::SCREEN_WIDTH = 640;
int Initilize::SCREEN_HEIGHT = 480;
int Initilize::SCREEN_BPP = 32;

Also, if these value never change, it would be good to make them const. The reason you need to add the above to your cpp file is because static member variables need to be defined outside of the class. static SDL_Surface* screen;, etc. inside your class is only a declaration, and not a definition. static members are considered special and is very similar to a global variable.

The reason for this is because static members are shared between all instances of your class. This means they can only be defined once and allowing the definition inside the class would cause multiple definitions to occur, so the C++ standard forces you to define it outside of your class (and also implies you should put the definition in a cpp file).

like image 107
Jesse Good Avatar answered Sep 28 '22 19:09

Jesse Good


in Initialize.cpp do

#include "Initialize.h"
#include "SDL/SDL.h"

// this is the new line to insert
SDL_Surface* Initialize::screen = 0;
int Initialize::SCREEN_WIDTH=...; // whatever you want to set it to
int Initialize::SCREEN_HEIGHT=...; // whatever you want to set it to
int Initialize::SCREEN_BPP=...; // whatever you want to set it to

and remove the #include "Initialize.cpp" line in main.cpp

instead do

#include "Initialize.hpp"

if you're using gcc, compile using

g++ -o <output-file> main.cpp Initialize.cpp <include flags like -I> <lib flags like -L>
like image 45
mohaps Avatar answered Sep 28 '22 21:09

mohaps