为什么我的代码会生成“未解析的外部符号”错误?

Why is my code generating an "Unresolved external symbol" error?

提问人:Guy Joel McLean 提问时间:10/19/2012 最后编辑:Coding MashGuy Joel McLean 更新时间:10/19/2012 访问量:1246

问:

我一直在编写我的代码,并声明并定义了所有必要的变量,并包含了必要的头文件。尽管如此,它还是给了我关于类构造函数中使用的任何函数的“未解析的外部符号”。

BowlingAlley.obj : error LNK2001: unresolved external symbol "private: void __thiscall     BowlingAlley::addToMasterArray(int * const,int * const)" (?addToMasterArray@BowlingAlley@@AAEXQAH0@Z)
1>BowlingAlley.obj : error LNK2001: unresolved external symbol "private: void __thiscall     BowlingAlley::createLaneArrays(void)" (?createLaneArrays@BowlingAlley@@AAEXXZ)
1>BowlingAlley.obj : error LNK2001: unresolved external symbol "int * laneVertices" (?laneVertices@@3PAHA)

我的头文件如下。

#pragma once

#include <stdio.h>
#include <iostream>
#include <array>



class BowlingAlley
{
private: 
    void createLaneArrays();
    void concatenateArrays(int array1[], int array2[], int containerArray[]);
    int getNewArrayLength(int array1[], int array2[]);
    //mutates an array creating the master draw array by using the two functions above
    void addToMasterArray( int array2[], int masterArray[]);

public:
        BowlingAlley(int width, int gHeight, int length);
    BowlingAlley();

};

实现如下所示

    #include "BowlingAlley.h"
#include <stdio.h>
#include <GL/glut.h> 
#include <math.h>
#include <iostream>

using namespace std;
//BowlingAlley class contains all of the vertex information for the alley and the backdrop itself




//the lane's vars
int laneVertices[];
int laneIndices[];
int alleyArray[];

int alleyLength;
int alleyWidth;
int guardHeight;



BowlingAlley::BowlingAlley(int width, int gHeight, int length)
{
    alleyLength = length;
    alleyWidth = width;
    guardHeight = gHeight;
    createLaneArrays();
    //the masterdrawarray doesn't exist yet, create it with size 0
    int* masterDrawArray = new int[0];
    //start adding the vert Arrays to the master array
    addToMasterArray(laneVertices, masterDrawArray);

}

void createLaneArrays()
{
    float laneVertices[]= {
        -alleyWidth/2,0,0, 
        alleyWidth/2,0,0,
        -alleyWidth/2,0,alleyLength,
        alleyWidth/2,0,alleyLength
    };

    float laneIndices[]= {0,1,2,1,2,3};
}

int getNewArrayLength(int array1[], int array2[])
{
    //the number of elements in arrays1/2
    float array1Size = sizeof(array1)/sizeof(int*);
    float array2Size = sizeof(array2)/sizeof(int*);
    //the length of the new array
    int newArrayLength = array1Size + array2Size; 
    //return it
    return newArrayLength;
}

void concatenateArrays(int array1[], int array2[], int containerArray[])
{
    //the number of elements in arrays1/2
    float array1Size = sizeof(array1)/sizeof(int);
    float array2Size = sizeof(array2)/sizeof(int);
    //the length of the new array
    int newArrayLength = array1Size + array2Size; 

    //loop through adding array1 to the new array
    for (int i = 0; i<array1Size; i++)
    {
        containerArray[i] = array1[i];
    }
    //loop through adding array2 to the new array
    for (int i = array1Size; i<newArrayLength; i++)
    {
        int j = i - array1Size;
        containerArray[i] = array2[j];
    }




}

void addToMasterArray(int array2[], int masterArray[])
{
    //create a temporary array to act as a kind of buffer whil we delete and reset the size of the drawing array
    int* tempArray = new int[(sizeof(masterArray)/sizeof(int))];
    //copy the contents over to the temp array.
    for(int i =0; i<(sizeof(masterArray)/sizeof(int)); i++)
    {
        tempArray[i] = masterArray[i];
    }

    //delete what drawingArray points to
    delete[] masterArray;
    //calculate the size of the new array
    int arrLength = getNewArrayLength(array2, masterArray);
    //resurrect a new and extended drawingArray from the ashes, big enough to accomodate both arrays.
    masterArray = new int[arrLength];
    //use our previously made concatenateArrays function to append the two arrays
    concatenateArrays(tempArray, array2, masterArray);

    cout <<"The number of elements in the Master Array is: "<< sizeof masterArray/sizeof masterArray[0]<<endl;


}

然后创建对象,并在另一个 .cpp 文件中调用 main 中的函数。

#include "BowlingAlley.h"
#include <stdio.h>
#include <GL/glut.h> 
#include <math.h>
#include "imageloader.h"
#include "BowlingAlley.h"

    ////////////////////////////////////////////// 
int main(int argc, char** argv) 
{
  glutInit(&argc, argv);    // GLUT Initialization 
  glutInitDisplayMode(GLUT_DEPTH|GLUT_RGB|GLUT_DOUBLE); // Initializing the Display mode
  glutInitWindowSize(800,600);  // Define the window size
  glutCreateWindow("Taken Bowl");   // Create the window, with caption.
        printf("\n========== McLeanTech Systems =========\nBecoming Sentient");
  init();   // All OpenGL initialization

 BowlingAlley* myBowlingAlley = new BowlingAlley(100,30,1000); //make us a bowling alley


  //-- Callback functions ---------------------
  glutDisplayFunc(display);
  glutKeyboardFunc(mykey);
  //glutMouseFunc(mymouse);
  glutSpecialFunc(processSpecialKeys);  

  glutMainLoop();   // Loop waiting for event 
}

我只是看不出我遗漏了什么。

C++ OOP unresolved-external

评论

3赞 Seth Carnegie 10/19/2012
您缺少成员函数的定义。BowlingAlley::

答:

3赞 Vyktor 10/19/2012 #1

因为你是在不带前缀的情况下实现这些函数。BowlingAlley::

这样一来,你就可以创建一组新的函数(而不是类的方法),然后就缺少实现了。

void createLaneArrays()
{
    float laneVertices[]= {
    // ...

应该是:

void BowlingAlley::createLaneArrays()
{
    float laneVertices[]= {
    // ...

他们每个人都是一样的。

并且您在 中遇到了另一个错误,其中您初始化了局部变量而不是使用类变量。createLaneArrays()laneVertices[]

您可能希望:

laneVertices = new float[6];

并且不要忘记在析构函数(或类似函数)中删除:detroy

delete [] laneVertices;
6赞 Mark Stevens 10/19/2012 #2

“未解析”的方法根本不是方法。您省略了类名。

改变:

void createLaneArrays()

自:

void BowlingAlley::createLaneArrays()

并对其他 2 个执行相同的操作。然后他们将成为班级的一部分。它们不会仅仅因为它们与 C# 或 Java 位于同一文件中而自动出现在类中

评论

0赞 Guy Joel McLean 10/19/2012
谢谢,非常可以理解。这让我措手不及,因为我以前使用过 C++,但它是一个大而混乱的代码,都在一个 .cpp 文件中。但是,我已经将BowlingAlley::放在了.h和.cpp文件中方法的前面,但是ARRAY仍然告诉我它尚未解决。我必须为数组声明做同样的事情(在 BowlingAlley::) 前面吗?
0赞 Mark Stevens 10/19/2012
基本答案是“是”,您可能希望所有数据和代码都以类名为前缀 - 成为类的一部分。我看到您有一个名为“laneVertices[]”的文件级数组,其类型为 int,而“createLaneArrays”中的一个数组名称完全相同,但数据类型不同。通常,成员变量以“m_”或类似前缀为前缀,以保持它们直截了当 - 对于编译器和程序员。此外,createLaneArrays() 中“创建”的数组只是被分配,然后在函数返回时消失。我不确定你是不是这么想的。
0赞 Guy Joel McLean 10/19/2012
是的,我已经注意到并对其进行了修改。它们都应该是浮点类型。我正在尝试使用“new”在类级别创建数组。laneVertices = new float[] (在 createLaneArrays() 中) 但是出于某种原因,编译器现在给了我“laneVertices 必须是可修改的 Ivalue。我以为这就是你定义(新)数组的方式。
0赞 Mark Stevens 10/19/2012
您使用“新”分配班级级别成员是正确的。我不知道你的新代码中的左值是什么,也许你有类似“float a[4] = new float[4]”的东西?您需要在类级别定义的“float* m_pArray;”和代码中的“m_pArray = new float[4];”。“new” 将返回一个指针,因此 '=' 左侧的表达式(左值)必须是指针类型。