c++静态变量的未定义引用[重复]

时间:2022-06-27 04:54:44

This question already has an answer here:

这个问题已经有了答案:

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:

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:

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:

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.

抱歉,如果代码被奇怪地格式化了,插入4个空格,把代码块弄得有点乱。

3 个解决方案

#1


15  

Add the following to your cpp file:

在cpp文件中添加以下内容:

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.

而且,如果这些价值永远不变,那么最好还是让它们保持一致。之所以需要将上述内容添加到cpp文件中,是因为需要在类之外定义静态成员变量。类内部的静态SDL_Surface*屏幕等只是一个声明,而不是定义。静态成员被认为是特殊的,并且与全局变量非常相似。

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

这是因为静态成员在类的所有实例之间共享。这意味着它们只能定义一次,允许类内的定义出现多个定义,因此c++标准迫使您在类之外定义它(也意味着您应该将定义放在cpp文件中)。

#2


2  

in Initialize.cpp do

在初始化。cpp做

#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

并删除#include“Initialize”。cpp main.cpp“线

instead do

而不是做

#include "Initialize.hpp"

if you're using gcc, compile using

如果您正在使用gcc,请使用compile

g++ -o <output-file> main.cpp Initialize.cpp <include flags like -I> <lib flags like -L>

#3


1  

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

似乎您从未初始化过vairables。您在初始化的start方法中分配它们,但是没有初始化它们。尝试添加一个int屏幕宽度;在您将它分配到源文件而不仅仅是头文件之前

#1


15  

Add the following to your cpp file:

在cpp文件中添加以下内容:

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.

而且,如果这些价值永远不变,那么最好还是让它们保持一致。之所以需要将上述内容添加到cpp文件中,是因为需要在类之外定义静态成员变量。类内部的静态SDL_Surface*屏幕等只是一个声明,而不是定义。静态成员被认为是特殊的,并且与全局变量非常相似。

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

这是因为静态成员在类的所有实例之间共享。这意味着它们只能定义一次,允许类内的定义出现多个定义,因此c++标准迫使您在类之外定义它(也意味着您应该将定义放在cpp文件中)。

#2


2  

in Initialize.cpp do

在初始化。cpp做

#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

并删除#include“Initialize”。cpp main.cpp“线

instead do

而不是做

#include "Initialize.hpp"

if you're using gcc, compile using

如果您正在使用gcc,请使用compile

g++ -o <output-file> main.cpp Initialize.cpp <include flags like -I> <lib flags like -L>

#3


1  

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

似乎您从未初始化过vairables。您在初始化的start方法中分配它们,但是没有初始化它们。尝试添加一个int屏幕宽度;在您将它分配到源文件而不仅仅是头文件之前