2 Klassen die sich gegenseitig benötigen - wie include endlosschleife umgehen?



  • Sicher, dass du include-guards gesetzt hast?



  • Du hast definitiv keine include-guards benutzt.
    Wie gesagt, die Implementierung darf nicht inline sein.
    Du könntest die Implementierung natürlich wieder in den Header packen (außerhalb der Klasse), aber das ist kein guter Stil und der Übersicht nicht gerade förderlich . 🙂

    Du könntest auch dein Design überdenken, ob das so wirklich nötig ist.



  • Ich hab jetzt die Klasse umgeschrieben und bei beiden Klassen die Forwarddeclaration der anderen benutzt, jedoch heult dann der Compiler:
    --------------------Konfiguration: 2D Engine - Win32 Debug--------------------
    Kompilierung läuft...
    main.cpp
    c:\dxsdk\include\dinput.h: DIRECTINPUT_VERSION undefined. Defaulting to version 0x0800
    Zusatz.cpp
    CBoundingBox.cpp
    d:\eigene dateien\code\aktuell\cboundingbox.cpp(28) : error C2027: Verwendung des undefinierten Typs "CModelFormat"
    d:\eigene dateien\code\aktuell\cboundingbox.h(14) : Siehe Deklaration von 'CModelFormat'
    d:\eigene dateien\code\aktuell\cboundingbox.cpp(28) : error C2227: Der linke Teil von '->_header' muss auf Klasse/Struktur/Union zeigen
    d:\eigene dateien\code\aktuell\cboundingbox.cpp(28) : error C2228: Der linke Teil von '.iVertizes' muss eine Klasse/Struktur/Union sein
    CModelFormat.cpp
    Fehler beim Ausführen von cl.exe.

    2D Engine.exe - 3 Fehler, 0 Warnung(en)

    (meine 2 Klassen sind nicht A und B sondern CModelFormat und CBoundingBox 😉 )

    Kevin

    Edit: habs jetzt - hatte nur vergessen in der .cpp die andere Klasse zu inkludieren! DANKE und nen guten Rutsch ins neue Jahr 😉



  • Du hast den Code immer noch im Header stehen. 🙄

    Ich habe doch gesagt, dass du nur Zeiger und Referenzen auf die Klasse verwenden kannst und nicht die Klasse selber.

    A.cpp muss ungefähr so aussehen:

    #include "A.h"
    // Die foward-declaration muss ersetzt werden durch die vollständige Deklaration von B, sonst kannst du B nicht benutzen:
    #include "B.h"
    
    void A::ChangeB(B* b)
    {
      // Das geht, weil der Code nicht inline ist und weil #include "B.h" davor ist:
      b->machWas();
    }
    


  • Hi,

    irgendwie hab ich den Eindruck, Surkevin liest gar nicht, was man schreibt... nicht nur hier, sondern auch mehrfach unter Spiele- & Grafik-Programmierung!

    ChrisM



  • mh bist dir da sicher? Ich nicht...meine Fragen in Spiele Grafikprogrammierung gingen hauptsächlich um Mathe, dessen Stoff ich erst in 3 Jahren lernen werde. Da ich zu Vektoren noch keine Vorkenntnisse hatte könnt ihr mir die daraus resultierenden Begriffsstutzigkeiten nicht verübeln. Ich hab oben außerdem meinen Post editiert (auch @ cd9000) - es funktioniert jetzt ja. Nehmt mir doch alles übel... frohes neues jahr



  • Da wir schon gerade dabei sind.
    In früheren Versionen von VC (bis Version 6 glaub ich)
    Erzeugte er Klassen ungefähr so:

    // Headerdatei
    #ifndef FOO_H
    #define FOO_H
    
    class Foo
    {
    // ...
    };
    
    #endif
    

    Ab VC.NET folgendermaßen:

    // Headerdatei
    #pragma once
    
    class Foo
    {
    // ...
    };
    

    Was ist der Unterschied zwischen den Defines und der pragmaanweisung in den neueren Versionen?
    Und was sollte man verwenden.

    PS: Iss jetzt nicht unbedingt ne C++ spezifische Sache, aber ich will nicht unbedingt einen extra Thread aufmachen 🤡

    wie kann man das aussehen einer Autometisch generierten C++-Klasse in VC.NET 2003 ändern? (Ich will nicht, dass er im Parameterlosen Konstruktor void hinenschreibt)

    Schönen Tag noch.



  • das pragma ist idr schneller, das define-konstrukt portabel.
    pragma ist compilerspezifisches, und bei once, nehm ich mal an, wird der compiler sich hüten, die datei ein zweites mal zu öffnen. bei define muss der (pre)compiler jedesmal die datei neu öffnen (wenn er nicht besonders intelligent ist)
    wie du es änderst weiß ich nicht, weil ich das studio nicht verwende. frag mal in den entsprechenden foren nach.



  • Danke für die Antwort. Werde mal im VisualC++ Forum nachfragen.



  • davie schrieb:

    das pragma ist idr schneller, das define-konstrukt portabel.

    Wobei man die Geschwindigkeit mit sogenannten redundanten Include-Guards (macht eigentlich nur bei großen Projekten sinn) deutlich verbessern kann.
    Redundante Include-Guards umschließen jede include-Anweisung mit einem extra Include-Guard:

    #ifndef A_HEADER_NAME_INCLUDED
    #define A_HEADER_NAME_INCLUDED
    
    #ifndef B_HEADER_NAME_INCLUDED
    #include "b.h"
    #endif
    
    #ifndef C_HEADER_NAME_INCLUDED
    #include "c.h"
    #endif
    
    #ifndef IOSTREAM_H_INCLUDED
    #include <iostream>
    #define IOSTREAM_H_INCLUDED
    #endif
    
    class A
    {
    B b;
    C c;
    ...
    };
    
    #endif
    

    So wird jede Header-Datei wirklich nur einmal geöffnet, egal wie oft sie in eine UE inkludiert wird. Das funktioniert natürlich nur, wenn man eine Namensstrategie für seine Include-Guards hat und diese auch konsequent anwendet. Für Standard-Header sollte man dann natürlich ebenfalls Guards definieren (siehe Beispiel).


Anmelden zum Antworten