Ich habe einige Fragen zur Initialisierung einer statischen Sammlung. Hier ist ein Beispiel, das ich, dass codiert scheint zu funktionieren:C++ Initialisierung eines statischen Stacks
#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;
}
Nun, dies ist der beste Weg, zu tun, was ich versuche zu erreichen? Aus irgendeinem Grund, wenn ich dieses exakt gleiche Schema in meinem echten Code versuche, ruft oben() Drucke Kauderwelsch. Könnte es einen Grund dafür geben?
Wenn mein Beispiel in Ordnung ist, werde ich vielleicht meinen echten Code veröffentlichen. Hier
ist der eigentliche 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();
Und da ich den Code nicht mit dem Stapel bekommen zu arbeiten, habe ich dafür im Moment entschieden:
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.");
}
Kann jemand einen Fehler im Code mit dem Stapel entdecken, oder verbessern Sie vielleicht meine hastig kodierte Abhilfe?
Warum dieses Ding nicht neu gestalten? Erstellen Sie einen LightManager, der die Lichter verwaltet. Dieser Code bricht das Prinzip der alleinigen Verantwortung, in dem Lichter nicht mehr nur Lichter sind, sondern sich selbst verwalten. Mit einem Manager Lichter können Lichter und Licht-Manager verwalten können. – GManNickG
Guter Punkt! Aber selbst wenn ich die statischen Daten in eine andere Klasse verschiebe, bin ich immer noch mit diesem seltsamen Initialisierungsproblem beschäftigt. –
Nun, wenn Sie es in einen LightManager verschieben, muss es nicht wirklich statisch sein, da Ihr LightManager der statische (allgemeine) Einstiegspunkt zum Verwalten von Lichtern sein wird. Das sagte, es wäre gut, dieses Problem zu verstehen. :) Lass dich einfach einen anderen Ansatz wissen. – GManNickG