Hello.
I have some questions about initializing a static collection. Here is an example I coded that seems to work:
#include <stack>
#include <iostream>
using namespace std;
class A
{
private:
static stack<int> numbers;
static stack<int> initializeNumbers();
public:
A();
};
A::A() { cout << numbers.top() << endl; }
stack<int> A::initializeNumbers()
{
stack<int> numbers;
numbers.push(42);
return numbers;
}
stack<int> A::numbers = initializeNumbers();
int main()
{
A a;
}
Now, is this the best way to do what I'm trying to accomplish? For some reason, when I try this exact same scheme in my real code, calling top() prints gibberish. Could there be any reason for this?
If my example is fine, perhaps I will resort to posting my real code.
Here is the real code:
Light.h
#ifndef LIGHT_H_
#define LIGHT_H_
#include <stack>
#include "Vector4.h"
class Light
{
private:
static stack<GLenum> availableLights;
static stack<GLenum> initializeAvailableLights();
public:
GLenum lightID;
Vector4 ambient, diffuse, specular, position, spotDirection;
GLfloat constantAttenuation, linearAttenuation, quadraticAttenuation, spotExponent, spotCutoff;
Light( const Vector4& ambient = Vector4(0.0, 0.0, 0.0, 1.0),
const Vector4& diffuse = Vector4(1.0, 1.0, 1.0, 1.0),
const Vector4& specular = Vector4(1.0, 1.0, 1.0, 1.0),
const Vector4& position = Vector4(0.0, 0.0, 1.0, 0.0),
const Vector4& spotDirection = Vector4(0.0, 0.0, -1.0, 0.0),
GLfloat constantAttenuation = 1.0,
GLfloat linearAttenuation = 0.0,
GLfloat quadraticAttenuation = 0.0,
GLfloat spotExponent = 0.0,
GLfloat spotCutoff = 180.0);
~Light();
};
#endif /*LIGHT_H_*/
Light.cpp
#include <stdexcept> // runtime_error
#include <iostream>
using namespace std;
#include "Light.h"
Light::Light( const Vector4& ambient,
const Vector4& diffuse,
const Vector4& specular,
const Vector4& position,
const Vector4& spotDirection,
GLfloat constantAttenuation,
GLfloat linearAttenuation,
GLfloat quadraticAttenuation,
GLfloat spotExponent,
GLfloat spotCutoff) :
ambient(ambient),
diffuse(diffuse),
specular(specular),
position(position),
spotDirection(spotDirection),
constantAttenuation(constantAttenuation),
linearAttenuation(linearAttenuation),
quadraticAttenuation(quadraticAttenuation),
spotExponent(spotExponent),
spotCutoff(spotCutoff)
{
// This prints gibberish.
cout << availableLights.size() << endl;
// The error is indeed thrown.
if(availableLights.empty())
throw runtime_error("The are no more available light identifiers.");
else
{
lightID = availableLights.top();
availableLights.pop();
}
}
Light::~Light() { availableLights.push(this -> lightID); }
stack<GLenum> Light::initializeAvailableLights()
{
stack<GLenum> availableLights;
availableLights.push(GL_LIGHT7);
availableLights.push(GL_LIGHT6);
availableLights.push(GL_LIGHT5);
availableLights.push(GL_LIGHT4);
availableLights.push(GL_LIGHT3);
availableLights.push(GL_LIGHT2);
availableLights.push(GL_LIGHT1);
availableLights.push(GL_LIGHT0);
return availableLights;
}
stack<GLenum> Light::availableLights = initializeAvailableLights();
And since I can't get the code with the stack to work, I've opted for this at the moment:
Light.h
#ifndef LIGHT_H_
#define LIGHT_H_
#include <stack>
#include "Vector4.h"
class Light
{
private:
static const unsigned int LIGHTS = 9;
static bool availableLights[];
static GLenum lights[];
static GLenum getAvailableLight();
public:
GLenum lightID;
Vector4 ambient, diffuse, specular, position, spotDirection;
GLfloat constantAttenuation, linearAttenuation, quadraticAttenuation, spotExponent, spotCutoff;
Light( const Vector4& ambient = Vector4(0.0, 0.0, 0.0, 1.0),
const Vector4& diffuse = Vector4(1.0, 1.0, 1.0, 1.0),
const Vector4& specular = Vector4(1.0, 1.0, 1.0, 1.0),
const Vector4& position = Vector4(0.0, 0.0, 1.0, 0.0),
const Vector4& spotDirection = Vector4(0.0, 0.0, -1.0, 0.0),
GLfloat constantAttenuation = 1.0,
GLfloat linearAttenuation = 0.0,
GLfloat quadraticAttenuation = 0.0,
GLfloat spotExponent = 0.0,
GLfloat spotCutoff = 180.0);
~Light();
};
#endif /*LIGHT_H_*/
Light.cpp
#include <stdexcept> // runtime_error
#include "Light.h"
Light::Light( const Vector4& ambient,
const Vector4& diffuse,
const Vector4& specular,
const Vector4& position,
const Vector4& spotDirection,
GLfloat constantAttenuation,
GLfloat linearAttenuation,
GLfloat quadraticAttenuation,
GLfloat spotExponent,
GLfloat spotCutoff) :
ambient(ambient),
diffuse(diffuse),
specular(specular),
position(position),
spotDirection(spotDirection),
constantAttenuation(constantAttenuation),
linearAttenuation(linearAttenuation),
quadraticAttenuation(quadraticAttenuation),
spotExponent(spotExponent),
spotCutoff(spotCutoff)
{
lightID = getAvailableLight();
}
Light::~Light()
{
for(unsigned int i = 0; i < LIGHTS; i++)
if(lights[i] == lightID)
availableLights[i] = true;
}
bool Light::availableLights[] = {true, true, true, true, true, true, true, true};
GLenum Light::lights[] = {GL_LIGHT0, GL_LIGHT1, GL_LIGHT2, GL_LIGHT3, GL_LIGHT4, GL_LIGHT5, GL_LIGHT6, GL_LIGHT7};
GLenum Light::getAvailableLight()
{
for(unsigned int i = 0; i < LIGHTS; i++)
if(availableLights[i])
{
availableLights[i] = false;
return lights[i];
}
throw runtime_error("The are no more available light identifiers.");
}
Can anyone spot an error in the code with the stack, or perhaps improve upon my hastily coded workaround?