[gelöst] static Variable macht Probleme



  • Hi, ich habe für ein Spiel folgende Klasse:

    #ifndef SHOT
    #define SHOT
    #include "ShotKind.hpp"
    #include "Time.hpp"
    #include "EventList.hpp"
    
    class ShotKind;
    class EventList;
    
    class Shot
    {
        private:
            ShotKind* Kind;
            Position Start;
            Position End;
            bool Detonated;
            Shot* Next;
            double Starttime;
            static Time* Clock;
            static EventList* EventList;
    
        public:
            Shot(Position start, Position end)
            : Start(start), End(end), Detonated(false), Next(0)
            {
                Starttime = Clock->GetTime();
            }
            bool Draw();
            bool GetDetonated() {return Detonated;}
    };
    
    #endif
    

    Die beiden static Variablen werden Global befüllt:

    //etc.
    #include "Time.hpp"
    #include "EventList.hpp"
    
        //Static-Deklarationen
        Time Clock();
        EventList EventList();
    
        Time* Shot::Clock = &Clock;
        Time* Event::Clock = &Clock;
        Time* EventList::Clock = &Clock;
        EventList* Shot::EventList = &EventList;
    
    int main()
    {
    //etc.
    

    Gegen den Zeiger auf Time hat mein Compiler nichts, aber gegen den auf EventList:

    C:\...\Shot.hpp|20|error: declaration of EventList*Shot::EventList'| C:\\...\\EventList.hpp|8|error: changes meaning of \EventList' from `class EventList'|
    ||=== Build finished: 2 errors, 0 warnings ===|

    Hier nochmal die Problemklasse:

    #ifndef EVENTLIST
    #define EVENTLIST
    #include "Position.hpp"
    #include "Event.hpp"
    #include "Time.hpp"
    
    class EventList
    {
        private:
            Event* FirstEvent;
            static Time* Clock;
    
        public:
            EventList()
            : FirstEvent(0) {}
            EventList(Event* firstEvent)
            : FirstEvent(firstEvent) {}
            void AddEvent(int Kind, Position Pos, double Radius, int Strange);
            void AddEvent(int Kind, Position Pos, double Radius, int Strange,
                          double Duration, double DamageDuration);
            Event* CheckEvent(Position Pos, double Radius);
            Event* CheckEvent(Event* AfterEvent, Position Pos, double Radius);
            Event* CheckEvent(Position Pos, double Width, double Height);
            Event* CheckEvent(Event* AfterEvent, Position Pos, double Width,
                              double Height);
            int CheckStrange(Event* Event, Position Pos, double Radius);
            int CheckStrange(Event* Event, Position Pos, double Width, double Height);
            void CleanUp();
    };
    
    #endif
    

    Ich komme einfach nicht drauf. Was mache ich anders als bei Time, dass hier die static-Variable nicht funktioniert?

    Danke für die Hilfe im voraus. 🙂



  • //Static-Deklarationen
        Time Clock();             // !!! Funktionsdeklaration!!!
        EventList EventList();    // Name ändern
    
        Time* Shot::Clock = &Clock;
        Time* Event::Clock = &Clock;
        Time* EventList::Clock = &Clock;
        EventList* Shot::EventList = &EventList;
    

    Ansonsten gehört die Initialisierung von static-Membern in die Implementierungsdatei der Klasse. wenn du das später wieder verwenden willst musst du jedesmal in der main.cpp wieder alles zusammenfrickeln.



  • Ich habe mir gerade gedacht, dass es dem Compiler vielleicht nicht passt, dass der zeiger auch EventList heißt, hab in deshalb in EventList* Events geändert. Jetzt tritt der Fehler nicht mehr auf, aber dafür ein anderes:

    #include "Shot.hpp"
    #include "Exceptions.hpp"
    #include "Time.hpp"
    #include "EventList.hpp"
    #include "Event.hpp"
    
        //Static-Deklarationen
        Time Clock;
        EventList EventList;
    
        Time* Shot::Clock = &Clock;
        Time* Event::Clock = &Clock;
        Time* EventList::Clock = &Clock;
        EventList* Shot::Events = &EventList;
    
    int main()
    {
    //etc.
    

    C:\...\main.cpp|18|error: cannot convert `Time**' to `Time*' in initialization|
    C:\...\main.cpp|19|error: cannot convert `Time**' to `Time*' in initialization|
    C:\...\main.cpp|20|error: cannot convert `Time**' to `Time*' in initialization|
    C:\...\main.cpp|21|error: expected constructor, destructor, or type conversion before '*' token|
    ||=== Build finished: 4 errors, 0 warnings ===|

    Ich hab nicht den leisesten Hauch einer Ahnung, wieso er meint ich hätte Time** angelegt. Und scheinbar erkennt er die Klasse EventList nicht. Vielleicht ist das auch noch der selbe Fehler, der schon vorher vorhanden war, nur, dass er sich anders ausdrückt. Bin grad echt ratlos. 😕



  • Mach mal die Klammern hinter den statischen Objekten weg, der Compiler interpretiert sie als Funktionen und nicht als Objekte.



  • Ja, habs grad editiert. is mir auch eben aufgefallen, ändert aber das Problem nicht.



  • @l'abra d'or, ich kann die also auch in der Header-Datei außerhalb der Klassendefinition initialisieren? Wusste ich gar nicht. ich dachte immer die muss man global oder zumindest am Anfang der main{} initialisieren.


  • Mod

    Little Programmer schrieb:

    EventList EventList;
    

    Deklariert ein Objekt Eventlist des Typs Eventlist. Jede folgende Verwendung des Namens bezieht sich auf das Objekt nicht den Typ, der Klassenname wird durch die Objektdeklaration verdeckt.
    Möglich ist die Verwendung per Klassenschlüsselwort, also

    class EventList* Shot::Events = &EventList;
    

    besser ist es aber, die doppelte Verwendung des Bezeichners zu vermeiden.



  • Danke, so ist die aktuelle Version:

    #include <SFML/Graphics.hpp>
    #include "Shot.hpp"
    #include "Exceptions.hpp"
    #include "Time.hpp"
    #include "EventList.hpp"
    #include "Event.hpp"
    
    using namespace std;
    
        //Globale Variablen
        sf::RenderWindow Screen(sf::VideoMode(1024, 768, 32), "Programm", sf::Style::Fullscreen);
    
        //Static-Deklarationen
        Time Clock(&Screen);
        EventList Events;
    
        Time* Shot::Clock = &Clock;
        Time* Event::Clock = &Clock;
        Time* EventList::Clock = &Clock;
        EventList* Shot::Events = &Events;
    
    int main()
    {
    //etc.
    

    Fehlermeldung unverändert. 😞

    C:\...\main.cpp|22|error: cannot convert `Time**' to `Time*' in initialization|
    C:\...\main.cpp|23|error: cannot convert `Time**' to `Time*' in initialization|
    C:\...\main.cpp|24|error: cannot convert `Time**' to `Time*' in initialization|
    C:\...\main.cpp|25|error: cannot convert `EventList**' to `EventList*' in initialization|
    ||=== Build finished: 4 errors, 0 warnings ===|


  • Mod

    Der Initialisierer einer statischen Membervariablen wird im Scope der Klasse auswertet (Ebenso wie bereits die Parametertypen in einer Memberfunktionsdefinion im Scope der Klasse ausgewertet werden), folglich verweist &Clock in

    Time* Shot::Clock = &Clock
    

    auf Shot::Clock, nicht auf die zuvor definierte globale Clock-Variable. Folglich:

    Time* Shot::Clock = &::Clock
    

    Der Rest analog.



  • Gelöst. War nur ein Namenskonflikt:

    //Static-Deklarationen
        Time GeneralClock(&Screen);
        EventList AllEvents;
    
        Time* Shot::Clock = &GeneralClock;
        Time* Event::Clock = &GeneralClock;
        Time* EventList::Clock = &GeneralClock;
        EventList* Shot::Events = &AllEvents;
    

    Die Zeiger hießen gleich wie das Objekt auf das sie zeigen.



  • Danke camper. 🙂


  • Mod


Anmelden zum Antworten