[C++] Cross-Class Variables?

Started by
17 comments, last by ToohrVyk 15 years, 9 months ago
I'm trying to place a string in SDL below the player's sprite... That will move with the player. I'm getting this error: LNK2001: unresolved external symbol "public: static int Player::y" for both x and y.
//Edited out the unrelated code
class Player
{
    public:
    static int x, y;
};

Player::Player()
{
    //Initialize the offsets
    x = 0;
    y = 0;
}

void StringInput::show()  
{
    //If the surface isn't blank
    if( text != NULL )
    {
        //Show the name
		apply_surface( Player::x, Player::y + 20, text, screen ); //How  can I call a variable from another class?
    }
}

I can't figure out how to use the x and y variables from Player in StringInput::show(). Thanks in advance!
Advertisement
void StringInput::show( Player *pPlayer )  {    //If the surface isn't blank    if( text != NULL )    {        //Show the name		apply_surface( pPlayer->x, pPlayer->y + 20, text, screen );    }}


Somewhat like that.
Holy crap, you can read!
Static member variables have to be defined globally outside the class definition (in addition to the declaration within the class).

int Player::x = 0;
int Player::y = 0;
Since you have declared the two members to be static, you have to define them somewhere outside the class definition. Like

int Player::x = 0;int Player::y = 0;


Otherwise, the linker fails to find their symbols and produces your error.

Also, for static members it is dangerous to define a value inside the constructor of their class, because all your Player classes will use the same and every instance of that class would override the actual values. If you have just one instance of your class, this won't be a problem but it is bad style anyway.

As a suggestion for your case: you don't have to declare the variables as static, since they are public (everyone has access). When you do that, you can have more than one Player class, with players who have different positions.
God is real... unless declared integer.
The above will work, but it doesn't look like what you want. It seems you're using Player as an instance of a class (ie, everything is static). This is not the done thing. Instead, make an instance of the Player class, and use that:

class Player{public:    int x, y;};// this pointer should be a boost::shared_ptrvoid StringInput::show(Player* player){    apply_surface(player->x, player->y + 20, text, screen);}


What you have now reeks of bad design. I can understand the sentiment (you will only have one player), but this is a case where "just making one" is fine. Hell, if you ever (in the future) implement multiplayer, you may find the way you've written your code will limit you.
[ search: google ][ programming: msdn | boost | opengl ][ languages: nihongo ]
Alright I hit one other snag. I got rid of the static variables and tried to use the pointer in show(Player* player), but I get error C2511 'void StringInput::show(Player *)' : overloaded member function not found in 'StringInput'.

I figured that I should just define show() in the class as:

class StringInput{   public:   void show( Player* ); //Tried with and without the * and the second player};


but then I get a host of errors in my timer class to limit the fps.
Post the full class. Are you including player.h, or forward declaring Player? Also consider using a (const) reference instead of a pointer:
class Player;class StringInput {public:    void show(const Player &);};
You'll need to show more code for that, the error is probably caused somewhere else. Also, it's helpful to post errors you get, maybe not all of them if its a lot, but at least the first few.
Lifted most of my code directly from LazyFoo.

All of this code is in player.h, but called in main.cpp.

class Player{    private:	//Skills	bool vanish;	int ability [3] [6];        public:	int x, y;        //The velocity of the dot    int xVel, yVel;    //Initializes the variables    Player();        //Takes key presses and adjusts the dot's velocity    void handle_input();        //Moves the dot    void move();        //Shows the dot on the screen    void show();};class StringInput{    private:    //The storage string    std::string str;        //The text surface    SDL_Surface *text;        public:    //Initializes variables    StringInput();        //Does clean up    ~StringInput();        //Handles input    void handle_input();        //Shows the message on screen    void show( Player* );    };void StringInput::show( Player* player )  {    //If the surface isn't blank    if( text != NULL )    {        //Show the name		apply_surface( player->x, player->y + 20, text, screen ); //How to call a variable from another class?    }}


Some of the errors I get when I change it to
void show( Player* player );
, which were working fine before, are in timer.h:

Timer::Timer(){    startTicks = 0; //error C2065: 'startTicks' : undeclared identifier    pausedTicks = 0; //same with these three    paused = false;    started = false;}void Timer::start(){ //error C2601: 'StringInput::show::Timer::start' : local function definitions are illegal. this line contains a '{' which has not yet been matched//Don't exactly know how StringInput and Timer classes have connected themselves...    started = true;        paused = false;        startTicks = SDL_GetTicks();    }


Hopefully that should fill in the gaps. :)
Quote:
void StringInput::show( Player* player )
{
//If the surface isn't blank
if( text != NULL )
{
//Show the name
apply_surface( player->x, player->y + 20, text, screen ); //How to call a variable from another class? }
}


Your closing brace for the if statement is in a comment, so the compiler continues including files, it thinks they are all inside show(). This confuses it - a lot.

This topic is closed to new replies.

Advertisement