Sign in to follow this  
Trillobit

static problem in c++

Recommended Posts

Hello, I'm doing a little space shooter game and because many of my objects of the same type will share some data I wanted to make it static. This is for example the vector list and class specifik images. However I fail to get it to work properly, here is a simple example that might show what I'm doing wrong.
 
class E
{
public:
	// //Test
	//static void run();
	static int test;
};
//int E::test = -12;
/*
void E::run()
{
	test = 99999;
}
*/
void main(){
	E::test = 10;
	//E::run();
}

Why does this issue a linker error? main.obj : error LNK2001: unresolved external symbol "public: static int E::test" (?test@E@@2HA) I tried the same thing but split over three files, 1: main.cpp 2: E.h 3: E.cpp, and then this works until I uncomment the static function run(). In which some other linker error occurs. If I'm doing something strange, is there any other way to do it? How is the correct syntax and use for static, and is there any special rules when it later comes to objects and not ints. Is there any special rules that involves static functions? Thanks for any help

Share this post


Link to post
Share on other sites
Could you please paste some code where you are attempting to do the same with classes.


#include <vector>

class E
{
public:
static std::vector<int> testVector;
};

std::vector<int> E::testVector;

int main( int argc, char* argv[] )
{
return 0;
}


That works fine.

Dave

Share this post


Link to post
Share on other sites
It should work the same way with objects.
E.g. for an object of a 3D vector, in Vector.h

class Vector {
public:

float x,y,z;

Vector(float a,float b,float c);

static Vector ZERO;

static void unzero();

};


and in Vector.cpp

Vector::Vector(float a,float b,float c)
: x(a), y(b), z(c) {}

Vector Vector::ZERO(0,0,0);

void Vector::unzero() {
ZERO.x = ZERO.y = ZERO.z = 1;
}



(Well, don't debate over the sense of unzero(); its just an example. ;)

Share this post


Link to post
Share on other sites
Quote:
Original post by Trillobit
Yes, for ints, but somehow, doing the same with classes does not work. Perhaps you could show me how to properly add a static vector and a static function?
The syntax posted by Colin Jeanne above applies to any variable type, including std::vector. If it's not working for you, post the errors you're getting and I'm sure it'll be easy to spot the problem.

You mentioned you got different link errors when the static function definition was in the .cpp file; perhaps you could post those as well. Also, you should probably post the exact code that results in the errors, including all #include directives, and with nothing commented out.

Share this post


Link to post
Share on other sites
Thanks for all replies.

here is my code:
----Main file----
 
#include "vgc.h" // VGC, a library to draw simple graphics.
#include <string>
#include <sstream>
//#include <iostream> // Not in use any more

#include "Entity.h"


class Engine
{
protected:
// M E M B E R V A R I A B L E S
// -----------------------------------------------
int width;
int height;
};//Class

class Zeroly : public Engine
{
// C O N S T R U C T O R
// -----------------------------------------------
public:

Zeroly::Zeroly()
{
initiate();

while( VGC::beginLoop(), mainloop() )
{
VGC::endLoop();
}
VGC::endLoop();
}

// M E M B E R F U N C T I O N S
// -----------------------------------------------
// Called by Contructor
private:


void initiate()
{
width = 800;
height = 600;
VGC::initialize( "Zeroly", width, height );
}

// This is the inside of the game loop
bool mainloop()
{
if ( keyDown( VGCKey::ESCAPE_KEY ) ){ return false; }// False = Exit

VGCDisplay::beginFrame();

Update();
//Clears the display and sets BackGround color -> Alpha, R, G, B
VGCDisplay::clear( VGCColor(255,125,125,125) ); //clear screen

VGCDisplay::endFrame();
return true;
}//function main loop

void Update()
{
//E::run();// = 200;
//Entity::updateAll();
}

// Called by Destructor
void terminate()
{
VGC::finalize();
}// Function Terminate

private:

// Interface to VGC
bool keyHit( VGCKey key ) { return VGCKeyboard::wasPressed( key ); }
bool keyDown( VGCKey key ){ return VGCKeyboard::isPressed( key ); }

// D E S T R U C T O R
// -----------------------------------------------
public:
~Zeroly()
{
terminate();
}

};//Class


int VGCMain( const VGCStringVector &arguments )
{
Zeroly Z; // Run Game
return 0;
}//main





---- Entity Header file ----
 
#pragma once
#include <vector>
#include "vgc.h"

class Entity
{
public:
Entity(void);
~Entity(void);
int getCount();

// Updates all entities
static void updateAll();

public://protected:
void update(void);

public:

VGCVector mPosition;
VGCVector mVelocity;
VGCVector mFrame; // Which image to draw in an animation
int mHealth, mSize, mCollisionDamage;

// Definition of STATIC member variables
//-----------------------------------------------
typedef std::vector<Entity*> Entity_Vector;
typedef Entity_Vector::iterator Entity_Iterator; //Used to loop the entities

// THESE STATICs does noot work because they are not initiated!
static Entity_Vector collection;// Lists all entities
static VGCImage mImage;
};



---- Entity cpp file ----
[source = lang("cpp")]
#include "Entity.h"
#include "vgc.h"

Entity_Vector Entity::collection;// Lists all entities

Entity::Entity(void)
{

}

Entity::~Entity(void)
{
}


int Entity::getCount()
{
return Entity::collection.size();
}

void Entity::updateAll()

// S T A T I C
//------------------------------------------------------------
// Updates all entities - is static
void Entity::updateAll()
{
// Loop all created entity objects - Player,Enemy,Shot

//Used to loop the entities
// NOTE: PASTED HERE IN DEBUGGIN PURPOSE - also in .h file
// typedef std::vector<Entity*> Entity_Vector;
// typedef Entity_Vector::iterator Entity_Iterator;

for( Entity_Iterator p = collection.begin(); p != collection.end(); p++ )
{
//(*p).update(); // see member function below
// ERROR!!
p->update()

if ( p->mHealth <= 0 )
{
collection.erase( p ); // collection is a static member of this class
delete (p);
}
}
return true;
}
//------------------------------------------------------------

void Entity::update(void)
{
collision();

mPosition += mVelocity;

VGCDisplay::renderImage(mImage, mFrame, mPosition, VGCAdjustment( 0.5, 0.5 );
}


void Entity::collision(void)
{
for( Entity_Iterator p = collection.begin(); p!= collection.end(); p++)
{
if ( &this != p )
{
int deltaX = this.mPosition- p->mPosition;
int deltaY = this.mPosition- p->mPosition;

if(((deltaX*deltaX) + (deltaY*deltaY)) <= ((this.mSize*this.mSize) + (2*this.mSize*(p->mSize)) + p->mSize * p->mSize ) )
{
mHealth -= p->mCollisionDamage;
}
}
} // next
}




I get this error: ..\Entity.h(21) : error C2146: syntax error : missing ';' before identifier 'mPosition'

Share this post


Link to post
Share on other sites
Hmm.. About the includes, should I include vgc in both Entity.h and Entity.cpp?

I tried switching those includes, I get this now:

.\Entity.cpp(4) : error C2143: syntax error : missing ';' before 'Entity::collection'

vgc.h includes a lot of files, including the vgcvector.

Share this post


Link to post
Share on other sites
Quote:
Original post by Trillobit
Hmm.. About the includes, should I include vgc in both Entity.h and Entity.cpp?

I tried switching those includes, I get this now:

.\Entity.cpp(4) : error C2143: syntax error : missing ';' before 'Entity::collection'

vgc.h includes a lot of files, including the vgcvector.
vgc.h doesn't need to be included in both Entity.h and Entity.cpp (the latter include is redundant and can be removed).

Also, you might try making the following change to your code:
typedef typename Entity_Vector::iterator Entity_Iterator;
This will probably fix the missing ';' error you mentioned.

Share this post


Link to post
Share on other sites
I added typename, like you said, and I get this error instead:
..\Entity.h(29) : error C2899: typename cannot be used outside a template declaration

Unfortunatly the other error seems to remain, second error is:
.\Entity.cpp(4) : error C2143: syntax error : missing ';' before 'Entity::collection'

And any comments on code style/design improvements is also very welcomed :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Trillobit
I added typename, like you said, and I get this error instead:
..\Entity.h(29) : error C2899: typename cannot be used outside a template declaration

Unfortunatly the other error seems to remain, second error is:
.\Entity.cpp(4) : error C2143: syntax error : missing ';' before 'Entity::collection'

And any comments on code style/design improvements is also very welcomed :)
Sorry, that was my mistake - the typename keyword is not required in this case. As for the 'missing ;' error, it's not immediately clear to me where that's coming from...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this