对 Base::object 链接器错误 @ c++ 的未定义引用带自由过剩
我有这个代码
/////////////////////////////////////Gnome.cpp 文件
#include "Living.h"
class Gnome:public Living{
private:
public:
Gnome();
void drawObjects();
};
Gnome::Gnome()
{
spriteImg = new Sprite("graphics/gnome.bmp"); //<-------------this is where it says there is the error
loaded = true;
}
///// //////////////////////////////Living.h 文件
#include <iostream>
#include "Sprite.h"
using namespace std;
class Sprite;
class Living{
protected:
int x,y;
static Sprite *spriteImg; //= NULL;
bool loaded;
void reset();
public:
Living();
~Living();
int getX();
void setX(int _x);
int getY();
void setY(int _y);
void virtual drawObjects() =0;
};
// Living.cpp
#include "Living.h"
Living::Living()
{
x=y=0;
reset();
}
Living::~Living()
{
delete spriteImg;
}
void Living::setX(int _x)
{
x=_x;
}
int Living::getX()
{
return x;
}
void Living::setY(int _y)
{
y=_y;
}
int Living::getY()
{
return y;
}
void Living::reset()
{
spriteImg = NULL;
loaded = false;
}
// sprite.h
#include <GL/glut.h>
#include <string>
using namespace std;
class ImageLoader;
class Sprite
{
public:
/**
* Enable 2D drawing mode to draw our sprites. This function MUST be called before
* any sprite is drawn on screen using the draw method.
*/
static void enable2D();
/**
* Disables the 2D drawing. This can be called before you are done drawing all 2D
* sprites and want to draw 3D now.
*/
static void disable2D();
Sprite(string filename);
virtual ~Sprite();
virtual void draw();
virtual void drawLiving(int dir, int flag); //flag=1 move
virtual void draw(int X, int Y);
virtual void rotate(GLint degrees);
// getter and setter methods
GLint getAngle() const;
void setAngle(GLint degrees);
void setX(GLdouble x);
void setY(GLdouble y);
GLint getHeight() const;
GLint getWidth() const;
/**
* Sets the pivot point in relation to the sprite itself, that is using the object
* coordiantes system. In this coordiantes system the bottom left point of the object
* is at (0, 0) and the top right is at (1, 1).
*
* E.g. to set the pivot to be in the middle of the sprite use (0.5, 0.5)
* Default values are (1, 1).
* @param pivotX Can be any value, but when x is in the range [0, 1] the pivot is inside the
* sprite where 0 is the left edge of the sprite and 1 is the right edge of the sprite.
* @param pivotY Can be any value, but when y is in the range [0, 1] the pivot is inside the
* sprite where 0 is the bottom edge of the sprite and 1 is the top edge of the sprite.
*/
void setPivot(GLfloat pivotX, GLfloat pivotY);
GLfloat getPivotX() const;
GLfloat getPivotY() const;
GLdouble getX() const;
GLdouble getY() const;
/**
* Sets the pivot to be at the point where object's pivot is set.
* @param obj The reference object to whose pivot we will set this pivot to be.
* Note: if the obj pivot changes or the obj moves after the setPivot call has
* been issued, the pivot of this object will not reflect this changes. You must
* call setPivot again with that object to update the pivot information.
*/
void setPivot(const Sprite &obj);
/**
* Sets the scale of the object. A scale of (1.0, 1.0) means the sprite
* maintains its original size. Values larger than 1 scale the sprite up
* while values less than 1 shrink it down.
*/
void setScale(GLfloat x, GLfloat y);
private:
ImageLoader *image;
GLuint textureID;
GLint angle;
GLdouble x;
GLdouble y;
GLfloat pivotX;
GLfloat pivotY;
GLfloat scaleX;
GLfloat scaleY;
GLint step;
//GLint dir;
//-----------------------------------------------------------------------------
// Initializes extensions, textures, render states, etc. before rendering
//-----------------------------------------------------------------------------
void initScene();
/**
* A helper function taken from http://www.opengl.org/resources/features/OGLextensions/
* to help determine if an OpenGL extension is supported on the target machine at run-time
* @param extension The extension name as a string.
* @return True if extension is supported and false if it is not.
*/
bool isExtensionSupported(const char *extension) const;
};
// 如果需要实现请让我知道
// 最后是引擎类
#include <conio.h>
#include "Living.h"
#include "Gnome.h"
using namespace std;
class Engine{
private:
vector<char*> gamemap;
int score;
vector <Living*> gameobjs;
void FindRandomPos(int &x_pos,int &y_pos);
int mapMaxX;
int mapMaxY;
void collisionDetecion(int pX,int pY);
public:
Engine();
void init(const char* mapname="defaultmap.txt",int gnomes=1,int traals=1,int diamonds=10);
void printMap();
void printMap2();
void movePotter();
void calculateScroll();
int getScore();
int getMapMaxX ();
int getMapMaxY ();
};
// 和部分engine.cpp,
void Engine::init(const char* mapname,int gnomes,int traals,int diamonds)
{
int i=0;
// int z=0;
mapMaxX=0;
mapMaxY=0;
int x_pos,y_pos;
int countobjs=0;
//gnomes
for(int i=0;i<gnomes;i++)
{
FindRandomPos(x_pos,y_pos);
gameobjs.push_back( new Gnome ); //<---------------here is where the error should begin i think
gameobjs[countobjs]->setX(x_pos);
gameobjs[countobjs]->setY(y_pos);
gamemap[gameobjs[countobjs]->getX()][gameobjs[countobjs]->getY()]='3';
countobjs++;
}
}
所以当我尝试构建它时,链接器显示此错误:对Living::spriteImg的未定义引用
I have this code
/////////////////////////////////////Gnome.cpp file
#include "Living.h"
class Gnome:public Living{
private:
public:
Gnome();
void drawObjects();
};
Gnome::Gnome()
{
spriteImg = new Sprite("graphics/gnome.bmp"); //<-------------this is where it says there is the error
loaded = true;
}
///////////////////////////////////Living.h file
#include <iostream>
#include "Sprite.h"
using namespace std;
class Sprite;
class Living{
protected:
int x,y;
static Sprite *spriteImg; //= NULL;
bool loaded;
void reset();
public:
Living();
~Living();
int getX();
void setX(int _x);
int getY();
void setY(int _y);
void virtual drawObjects() =0;
};
// living.cpp
#include "Living.h"
Living::Living()
{
x=y=0;
reset();
}
Living::~Living()
{
delete spriteImg;
}
void Living::setX(int _x)
{
x=_x;
}
int Living::getX()
{
return x;
}
void Living::setY(int _y)
{
y=_y;
}
int Living::getY()
{
return y;
}
void Living::reset()
{
spriteImg = NULL;
loaded = false;
}
// sprite.h
#include <GL/glut.h>
#include <string>
using namespace std;
class ImageLoader;
class Sprite
{
public:
/**
* Enable 2D drawing mode to draw our sprites. This function MUST be called before
* any sprite is drawn on screen using the draw method.
*/
static void enable2D();
/**
* Disables the 2D drawing. This can be called before you are done drawing all 2D
* sprites and want to draw 3D now.
*/
static void disable2D();
Sprite(string filename);
virtual ~Sprite();
virtual void draw();
virtual void drawLiving(int dir, int flag); //flag=1 move
virtual void draw(int X, int Y);
virtual void rotate(GLint degrees);
// getter and setter methods
GLint getAngle() const;
void setAngle(GLint degrees);
void setX(GLdouble x);
void setY(GLdouble y);
GLint getHeight() const;
GLint getWidth() const;
/**
* Sets the pivot point in relation to the sprite itself, that is using the object
* coordiantes system. In this coordiantes system the bottom left point of the object
* is at (0, 0) and the top right is at (1, 1).
*
* E.g. to set the pivot to be in the middle of the sprite use (0.5, 0.5)
* Default values are (1, 1).
* @param pivotX Can be any value, but when x is in the range [0, 1] the pivot is inside the
* sprite where 0 is the left edge of the sprite and 1 is the right edge of the sprite.
* @param pivotY Can be any value, but when y is in the range [0, 1] the pivot is inside the
* sprite where 0 is the bottom edge of the sprite and 1 is the top edge of the sprite.
*/
void setPivot(GLfloat pivotX, GLfloat pivotY);
GLfloat getPivotX() const;
GLfloat getPivotY() const;
GLdouble getX() const;
GLdouble getY() const;
/**
* Sets the pivot to be at the point where object's pivot is set.
* @param obj The reference object to whose pivot we will set this pivot to be.
* Note: if the obj pivot changes or the obj moves after the setPivot call has
* been issued, the pivot of this object will not reflect this changes. You must
* call setPivot again with that object to update the pivot information.
*/
void setPivot(const Sprite &obj);
/**
* Sets the scale of the object. A scale of (1.0, 1.0) means the sprite
* maintains its original size. Values larger than 1 scale the sprite up
* while values less than 1 shrink it down.
*/
void setScale(GLfloat x, GLfloat y);
private:
ImageLoader *image;
GLuint textureID;
GLint angle;
GLdouble x;
GLdouble y;
GLfloat pivotX;
GLfloat pivotY;
GLfloat scaleX;
GLfloat scaleY;
GLint step;
//GLint dir;
//-----------------------------------------------------------------------------
// Initializes extensions, textures, render states, etc. before rendering
//-----------------------------------------------------------------------------
void initScene();
/**
* A helper function taken from http://www.opengl.org/resources/features/OGLextensions/
* to help determine if an OpenGL extension is supported on the target machine at run-time
* @param extension The extension name as a string.
* @return True if extension is supported and false if it is not.
*/
bool isExtensionSupported(const char *extension) const;
};
// if you need the implementation plz let me know
//and finally the engine class
#include <conio.h>
#include "Living.h"
#include "Gnome.h"
using namespace std;
class Engine{
private:
vector<char*> gamemap;
int score;
vector <Living*> gameobjs;
void FindRandomPos(int &x_pos,int &y_pos);
int mapMaxX;
int mapMaxY;
void collisionDetecion(int pX,int pY);
public:
Engine();
void init(const char* mapname="defaultmap.txt",int gnomes=1,int traals=1,int diamonds=10);
void printMap();
void printMap2();
void movePotter();
void calculateScroll();
int getScore();
int getMapMaxX ();
int getMapMaxY ();
};
//and the partial engine.cpp
void Engine::init(const char* mapname,int gnomes,int traals,int diamonds)
{
int i=0;
// int z=0;
mapMaxX=0;
mapMaxY=0;
int x_pos,y_pos;
int countobjs=0;
//gnomes
for(int i=0;i<gnomes;i++)
{
FindRandomPos(x_pos,y_pos);
gameobjs.push_back( new Gnome ); //<---------------here is where the error should begin i think
gameobjs[countobjs]->setX(x_pos);
gameobjs[countobjs]->setY(y_pos);
gamemap[gameobjs[countobjs]->getX()][gameobjs[countobjs]->getY()]='3';
countobjs++;
}
}
so when I try to build it, the linker shows this error: Undefined reference to Living::spriteImg
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个链接器错误,它告诉您链接器无法找到
static
成员Living::spriteImg
的定义,这是因为您刚刚声明 它在你的班级中,但你从未定义它。您需要在
Living.cpp
中定义静态成员:请记住,您需要在一个且仅有一个
.cpp
文件中定义它。好读:
定义和声明之间有什么区别?< /a>
It is a Linker error, which tells you that the Linker cannot find definition for the
static
memberLiving::spriteImg
, this is because you just declare it in your class but you never defined it.You ned to define the static member in your
Living.cpp
:Remember that you need to define it in one and only one
.cpp
file.Good Read:
What is the difference between a definition and a declaration?
Living::SpriteImg
是一个static
数据成员。您仅在Living 类
中声明了它。但是,静态数据成员也需要单独定义,最好在 .cpp 文件中定义。
Living::SpriteImg
is astatic
data member. You have only declared it in theclass Living
.However,
static
data members also needs to be defined separately, preferably in a.cpp
file.