Static Variables in a Class

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
XianForce
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 767
Joined: Wed Oct 29, 2008 8:36 pm

Static Variables in a Class

Post by XianForce »

Well after reading LazyFoo's tutorial on Particle Engines I decided to add in a simple one myself. I have a few surfaces to be used and I don't want them to be created for every particle, cause that's unnecessary. I tried to declare them as static but I'm having a lot of trouble with them. From what I've read, the static variables don't belong to any instance, and don't even need an instance. I hear they must be initialized to be in scope, but they can't be initialized in the class or a header file. I'm not sure how correct that is, but I'm assuming it's pretty correct.

Anyways, how would someone go about using the static variables in such a way that:

They are not global.
The header file declaring the class is there so that it can be included into other files so other files can use the methods from the Particle class
And the class methods are not re-defined.


I've had some trouble with this, so hopefully someone can point me in the right direction. If global scope is the way to go, tell me, I just hear that that's bad practice =p.
User avatar
MarauderIIC
Respected Programmer
Respected Programmer
Posts: 3406
Joined: Sat Jul 10, 2004 3:05 pm
Location: Maryland, USA

Re: Static Variables in a Class

Post by MarauderIIC »

Integers can be initialized as static inside a class definition.

Code: Select all

class MyClass {
    static int myInt = 1;
};
Other variable types must be initialized after the class definition.

Code: Select all

class MyClass {
    static int myInt = 1;
    static float myFloat;
};

float MyClass::myFloat = 1.234;

Code: Select all

class MyClass {
    static int myInt;
    static float myFloat;
};

int MyClass::myInt = 1;
float MyClass::myFloat = 1.234;
The same methods are used for static const member variables.

This short program that I wrote straight into the forum and haven't tested demonstrates statics:

Code: Select all

#include <iostream>
using namespace std;

/* can be put into a header file */
class MyClass {
public:
    static float myFloat;
};

float MyClass::myFloat = 1.234;
/* end possible header file */

int main() {
    MyClass class1;
    MyClass class2;

    class1.myFloat = 5.678; //set using class1
    cout << class2.myFloat; //output using class2
    MyClass::myFloat = 9.0123; //set using class
    cout << class2.myFloat << endl //output using class2
         << MyClass::myFloat; //output using class
    return 0;
}
Output:

Code: Select all

5.678 //which we set using class 1
9.0123 //which we set using MyClass and output using class2
9.0123 //which we output using MyClass 
I realized the moment I fell into the fissure that the book would not be destroyed as I had planned.
XianForce
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 767
Joined: Wed Oct 29, 2008 8:36 pm

Re: Static Variables in a Class

Post by XianForce »

Thanks a ton Mar. That was much more help than I even dreamed of =D

EDIT: Now I'm getting multiple definition errors. I'm guessing because it's at the bottom of the header file I'm including in different places, so it's defined in multiple places/files.

So how do I get around that =p?
User avatar
MarauderIIC
Respected Programmer
Respected Programmer
Posts: 3406
Joined: Sat Jul 10, 2004 3:05 pm
Location: Maryland, USA

Re: Static Variables in a Class

Post by MarauderIIC »

Try moving the static initialization out of the header and to the top of your class's associated .cpp file instead (the same file you define its functions in, you know what I mean).
I realized the moment I fell into the fissure that the book would not be destroyed as I had planned.
XianForce
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 767
Joined: Wed Oct 29, 2008 8:36 pm

Re: Static Variables in a Class

Post by XianForce »

MarauderIIC wrote:Try moving the static initialization out of the header and to the top of your class's associated .cpp file instead (the same file you define its functions in, you know what I mean).
When I do that I get a segfault because it's initializing it before SDL initializes. It seems if I put it anywhere else so that it does initialize first, I get a redeclaration error =/.
andrew
Chaos Rift Regular
Chaos Rift Regular
Posts: 121
Joined: Mon Dec 08, 2008 2:12 pm

Re: Static Variables in a Class

Post by andrew »

XianForce wrote:EDIT: Now I'm getting multiple definition errors. I'm guessing because it's at the bottom of the header file I'm including in different places, so it's defined in multiple places/files.
Are you using guards in your header files?

Example:

Code: Select all

#ifndef __DEBUG_H__
#define __DEBUG_H__

#include <fstream>

class Debug
{
    public:
        Debug();
        ~Debug();
        void Log(char c[]);
        std::ofstream& operator<<(char c[]);
        std::ofstream& operator<<(int i);
        std::ofstream& operator<<(float f);
        std::ofstream& operator<<(bool b);
        void Endl(int nr);
};

static Debug debug;

#endif      // __DEBUG_H__
XianForce
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 767
Joined: Wed Oct 29, 2008 8:36 pm

Re: Static Variables in a Class

Post by XianForce »

andrew wrote:
XianForce wrote:EDIT: Now I'm getting multiple definition errors. I'm guessing because it's at the bottom of the header file I'm including in different places, so it's defined in multiple places/files.
Are you using guards in your header files?

Example:

Code: Select all

#ifndef __DEBUG_H__
#define __DEBUG_H__

#include <fstream>

class Debug
{
    public:
        Debug();
        ~Debug();
        void Log(char c[]);
        std::ofstream& operator<<(char c[]);
        std::ofstream& operator<<(int i);
        std::ofstream& operator<<(float f);
        std::ofstream& operator<<(bool b);
        void Endl(int nr);
};

static Debug debug;

#endif      // __DEBUG_H__

Yeah I am
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: Static Variables in a Class

Post by short »

It looks like your still declaring it in the header file. Try the actual .cpp file
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
XianForce
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 767
Joined: Wed Oct 29, 2008 8:36 pm

Re: Static Variables in a Class

Post by XianForce »

short0014 wrote:It looks like your still declaring it in the header file. Try the actual .cpp file
I've tried in both.

Initializing it in the classes header file produces a multiple declaration. Initializing it in the C++ produces a segfault (same reason for why it can't be global). Initializing it anywhere else produces a redeclaration error.
User avatar
MarauderIIC
Respected Programmer
Respected Programmer
Posts: 3406
Joined: Sat Jul 10, 2004 3:05 pm
Location: Maryland, USA

Re: Static Variables in a Class

Post by MarauderIIC »

Since it seems to be SDL-dependent, initialize it to NULL first and then set it to whatever you want after you've initialized SDL.
I realized the moment I fell into the fissure that the book would not be destroyed as I had planned.
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: Static Variables in a Class

Post by dandymcgee »

XianForce wrote:
short0014 wrote:It looks like your still declaring it in the header file. Try the actual .cpp file
I've tried in both.

Initializing it in the classes header file produces a multiple declaration. Initializing it in the C++ produces a segfault (same reason for why it can't be global). Initializing it anywhere else produces a redeclaration error.
Can you post the relevant code (where you are initializing it in the .cpp file)?

Edit: Mar beat me, try that first. ;)
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
XianForce
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 767
Joined: Wed Oct 29, 2008 8:36 pm

Re: Static Variables in a Class

Post by XianForce »

MarauderIIC wrote:Since it seems to be SDL-dependent, initialize it to NULL first and then set it to whatever you want after you've initialized SDL.
Tried... I set it to NULL at the top of the .cpp and then I loaded the surface in another function, after SDL is initialized.

I got a redeclaration error from where I loaded it in the function. It said it was already declared in the header file, the line number was the number where I just declared what was in the class. So like:

Code: Select all

class Particle
{
        private:
                static SDL_Surface* surRed;
}

//then over in some other function...
void someFunc()
{
        SDL_Surface* Particle::surRed = load(); // This is a redeclaration of the above.
}
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: Static Variables in a Class

Post by dandymcgee »

XianForce wrote:
Tried... I set it to NULL at the top of the .cpp and then I loaded the surface in another function, after SDL is initialized.

I got a redeclaration error from where I loaded it in the function. It said it was already declared in the header file, the line number was the number where I just declared what was in the class. So like:

Code: Select all

class Particle
{
        private:
                static SDL_Surface* surRed;
}

//then over in some other function...
void someFunc()
{
        SDL_Surface* Particle::surRed = load(); // This is a redeclaration of the above.
}
Right.

Try this (omit "Particle::" if you're defining surRed inside a member function of the Particle class):

Code: Select all

void someFunc()
{
        Particle::surRed = load();
}
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
XianForce
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 767
Joined: Wed Oct 29, 2008 8:36 pm

Re: Static Variables in a Class

Post by XianForce »

dandymcgee wrote:
XianForce wrote:
Tried... I set it to NULL at the top of the .cpp and then I loaded the surface in another function, after SDL is initialized.

I got a redeclaration error from where I loaded it in the function. It said it was already declared in the header file, the line number was the number where I just declared what was in the class. So like:

Code: Select all

class Particle
{
        private:
                static SDL_Surface* surRed;
}

//then over in some other function...
void someFunc()
{
        SDL_Surface* Particle::surRed = load(); // This is a redeclaration of the above.
}
Right.

Try this (omit "Particle::" if you're defining surRed inside a member function of the Particle class):

Code: Select all

void someFunc()
{
        Particle::surRed = load();
}

That worked, thanks =D
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: Static Variables in a Class

Post by dandymcgee »

XianForce wrote: That worked, thanks =D
You're welcome. 8-)
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
Post Reply