Vorabdeklaration von Structs



  • Hallo

    Kann man structs auch vorab deklarieren wie Klassen?
    Weil sonst krieg ich ein Puff mit dem Linker 😞

    Brauche in einer Klasse eine Referenz auf ein Struct.

    Foo.h

    #include Bar // <-- Problem!
    
    class Foo
    {
    public:
        Foo( Bar& bar ): bla_( bar.bla ), blubb_( bar.blubb ) {}
    private:
        string bla_;
        int blubb_;
    };
    

    Bar.h

    struct Bar
    {
        string bla;
        int blubb;
    };
    
    Bar bar = { "Bla", 42 };
    

    Main.cpp

    #include "Foo.h"
    #include "Bar.h"
    
    int Main()
    {
        Foo foo( bar );
    }
    

    ...
    Foo.obj : error LNK2005: "struct Bar bar" (?bar@@3UBar@@A) already defined in Main.obj



  • Ok erledigt!
    Mit extern gehts!

    Foo.h

    #include "Bar.h"
    
    class Foo
    {
    public:
        Foo( Bar& bar ): bla_( bar.bla ), blubb_( bar.blubb ) {}
    private:
        string bla_;
        int blubb_;
    };
    

    Bar.h

    struct Bar
    {
        string bla;
        int blubb;
    };
    

    Bar.cpp (neu)

    #include "Bar.h"
    
    Bar bar = { "Bla", 42 };
    

    Main.cpp

    #include "Foo.h"
    #include "Bar.h"
    
    extern Bar bar; // <-- Hier!
    
    int Main()
    {
        Foo foo( bar );
    }
    


  • Hallo

    dein Problem ist nicht die Definition des structs, sondern die Deklarierung und Initialisierung der Inbstanz bar. Denn das darf pro Übersetzungseinheit nur einmal gemacht werden, wird aber in deiner main.cpp verletzt.

    Schau dich nach dem korrekten Einsatz von Include-Guards und dem Schlüsselwort extern um.

    /Edit : zu langsam. Aber irgendwie habe ich mir das anders vorgestellt
    Bar.h

    struct Bar
    {
        string bla;
        int blubb;
    };
    extern Bar bar; // <-- Hier! und nicht in main.cpp
    

    bis bald
    akari



  • Trotzdem danke, akari 👍



  • Hallo

    hoffentlich liest du aber nochmal meine neue Anmerkung durch.

    bis bald
    akari



  • Ja hab ich grad gesehn. Tut was es soll.
    Aber warum nicht in der Main?
    Und die Trennung in Bar.h und Bar.cpp ist ok so, oder?



  • Hallo

    Und die Trennung in Bar.h und Bar.cpp ist ok so, oder?

    Ist nicht nur korrekt, sondern auch notwendig.

    Aber warum nicht in der Main?

    Weil in deiner Variante jetzt zwei verschiedene Instanzen Bar bar vorhanden sind, eine global in Bar.cpp (und nur dort sichtbar) und eine in main.cpp (und nur dort verwendet). Das heißt die haben auch verschiedene Werte, kannst ruhig mal testen.
    In meiner Version hingegen gibt es nur ein globales bar, worauf auf alle 3 Codedateien zugegriffen wird.

    bis bald
    akari



  • @akari: Die Variablen sind schon identisch (extern weißt ja den Compiler an, die Suche nach dieser Variable an den Linker zu übergeben, der dann die Variable aus der bar.cpp findet).

    @Optimist: Klar funktioniert es, wenn du in jeder Datei deine Deklarationen wiederholst (theoretisch könntest du auch auf "#include" verzichten und alle Prototypen direkt in deinen Quellcode einkopieren). Aber das ist sehr aufwändig und fehleranfällig (wenn alle beteiligten CPP's den selben Header einbinden, hast du definitiv überall den selben Prototyp - wenn du die Deklarationen überall wiederholst, reicht ein Tippfehler und der Linker findet nichts wieder).


Anmelden zum Antworten