LNK2005(已定义)找不到错误

LNK2005 (already defined) can't find error

我有一个看似常见的问题,但我似乎无法在我的代码上下文中解决它。我最近开始了一个 class,我在没有 C++ 知识的情况下被扔进了 C++ 和 OpenGL,所以请对我放轻松。这是我的 3 个文件,用于打开 OpenGL window;然而,我收到了一个不错的 LNK2005 错误:

error LNK2005: "public: static unsigned int JWindow::id" (?id@JWindow@@2IA) already defined in Application.obj X:\School\comp2501\COMP2501Tutorial1\COMP2501Tutorial1\Main.obj ‌​COMP2501Tutorial1

我似乎找不到我在哪里重新定义了给我这个错误的东西。

main.cpp

#include <windows.h>       // Standard header for MS JWindows applications
#include <freeglut.h>
#include "Application.h"

#define KEY_ESCAPE 27

static GLfloat lightPos[] = { 1.0, 1.0, 1.0, 0.0 };

void drawCube(GLdouble x0, GLdouble x1, GLdouble y0, GLdouble y1, GLdouble z0, GLdouble z1) {/**/}

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

    JWindow::create(640, 480, "Tutorial 1", 45.0f, 0.1f, 500.0f);

    // initialize and run program
    glutInit(&argc, argv);                                      // GLUT initialization
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);  // Display Mode (RGBA color|two screen buffers| use depth buffer)

    glutInitWindowSize(JWindow::width, JWindow::height);                // set JWindow size

    glutDisplayFunc(JWindow::display);                                  // register display function
    glutIdleFunc(JWindow::display);                                     // register idle function
    glutKeyboardFunc(JWindow::keyboard);                                    // register keyboard function
    glutCloseFunc(JWindow::close);                                       // register close function


    JWindow::initialize();                                              // intialization
     glutMainLoop();                                                // run GLUT mainloop
}

Application.h

class JWindow{
public:
    static void updateProjection();
    static void render();
    static void initialize();
    static void timer(int);
    static void display();
    static void close();
    static void create(int, int, char*, float, float, float);
    static void keyboard(unsigned char, int, int);

    static GLuint id;
    static char* title;

    static int width;
    static int height;

    static float fovAngle;

    static float zNear;
    static float zFar;

};


GLuint JWindow::id = 0;
char* JWindow::title = "JWindow";
int JWindow::width = 0;
int JWindow::height = 0;
float JWindow::fovAngle = 0.0f;
float JWindow::zNear = 0.0f;
float JWindow::zFar = 0.0f;

Application.cpp

#include <freeglut.h>
#include "Application.h"

#define KEY_ESCAPE 27

void JWindow::updateProjection()
{
    glutSetWindow(JWindow::id);                                                      // tell opengl which JWindow you want to change
    JWindow::height = (JWindow::height < 1) ? 1 : JWindow::height;                            // make sure we are not dividing by zero for the aspect
    glViewport(0, 0, JWindow::width, JWindow::height);                                  // set the viewport

    glMatrixMode(GL_PROJECTION);                                                // select projection matrix
    glLoadIdentity();                                                           // reset projection matrix

    GLfloat aspect = (GLfloat)JWindow::width / JWindow::height;                           // calculate aspect ratio
    gluPerspective(JWindow::fovAngle, aspect, JWindow::zNear, JWindow::zFar);       // set up a perspective projection matrix
 }


// Render data to the screen
void JWindow::render()
{
glClearColor(0.25f, 0.25f, 0.25f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);          // Clear Screen and Depth Buffer
glMatrixMode(GL_MODELVIEW);                                  // Tell opengl we are working with the modelview matrix
glLoadIdentity();                                            // Set the modelview matrix to the identity matrix

gluLookAt(0.0f, 0.0f, 10.0f,    //position
    0.0f, 0.0f, 0.0f,     //look at position
    0.0f, 1.0f, 0.0f);    //up vector
/*
glBegin(GL_TRIANGLES);              // Send the following information as triangles
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);  // glColor4f(red,green,blue,alpha)
glVertex3f(-1.0f, -1.0f, 0.0f);     // glVertex3f(x,y,z)

glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 0.0f);

glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 0.0f);

glEnd();                            // tell opengl we are done sending data
*/
    //drawCube(-1, 1, -1, 1, -1, 1);
    glutSolidTorus(1, 2, 10, 10);
    glutSwapBuffers(); //works with GL_DOUBLE. use glFlush(); instead, if using GL_SINGLE
}

// Function called when timer ends
void JWindow::timer(int id) {
    glutPostRedisplay();         // Tell GLUT to call it's glutDisplayFunc
}

// Set new timer and render
void JWindow::display(void)
{
    glutTimerFunc(17, timer, 1); //Call timer function in at least 17 milliseconds
    glutSetWindow(JWindow::id);      //Tell glut which JWindow we are working on (only needed for multiple JWindows)
JWindow::render();           //Call our render function
}

//get keyboard input
void JWindow::keyboard(unsigned char key, int mousePositionX, int mousePositionY)
{
    switch (key)
    {
    case KEY_ESCAPE:
        glutExit();    //if ESC key is pressed, quit
        break;

    default:
        break;
    }
}

// callback function when glut ends
void JWindow::close()
{
    //memory cleanup when program quits
}

void JWindow::initialize()
{
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
    glClearColor(0.0, 0.0, 0.0, 1.0);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    glViewport(0, 0, JWindow::width, JWindow::height);                      // set the viewport

    glMatrixMode(GL_PROJECTION);                                    // select projection matrix
    glLoadIdentity();                                               // reset projection matrix
    GLfloat aspect = (GLfloat)JWindow::width / JWindow::height;             // calculate aspect ratio
    gluPerspective(JWindow::fovAngle, aspect, JWindow::zNear, JWindow::zFar);   // set up a perspective projection matrix

}

void reshape(GLint newWidth, GLint newHeight) {

}

void JWindow::create(int w, int h, char* t, float fov, float n, float f){
    JWindow::width = w;
    JWindow::height = h;
    JWindow::title = t;
    JWindow::fovAngle = fov;
    JWindow::zNear = n;
    JWindow::zFar = f;
    JWindow::id = glutCreateWindow(JWindow::title);
}

您应该将静态成员的初始化移动到您的 Application.cpp 文件中:

GLuint JWindow::id = 0;
char* JWindow::title = "JWindow";
int JWindow::width = 0;
int JWindow::height = 0;
float JWindow::fovAngle = 0.0f;
float JWindow::zNear = 0.0f;
float JWindow::zFar = 0.0f;

这些是静态成员的定义。如果您将它们包含在多个翻译单元中(您已经完成),则您有多个定义。