提问人:Guy Joel McLean 提问时间:10/19/2012 最后编辑:Coding MashGuy Joel McLean 更新时间:10/19/2012 访问量:1246
为什么我的代码会生成“未解析的外部符号”错误?
Why is my code generating an "Unresolved external symbol" error?
问:
我一直在编写我的代码,并声明并定义了所有必要的变量,并包含了必要的头文件。尽管如此,它还是给了我关于类构造函数中使用的任何函数的“未解析的外部符号”。
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
}
我只是看不出我遗漏了什么。
答:
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” 将返回一个指针,因此 '=' 左侧的表达式(左值)必须是指针类型。
评论
BowlingAlley::