c++ undefined reference to static variable [duplic

2019-04-23 12:57发布

问题:

This question already has an answer here:

  • static variable link error 2 answers

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.

回答1:

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).



回答2:

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>


回答3:

It appears that you never initialized your vairables. You are assigning them in the Initialize start method but didn't initialize them. Try adding in a int SCREENWIDTH; before you assign it in the source not just header file