Versuche, mir friends zu machen ...



  • Ich habe eine Klasse Auto, die als Attribute die Anzahl ihrer Türen und Reifen hat. Dazu noch eine Klasse Monteur, die die Reifen eines zu reparierenden Autos ausprinten soll. Deswegen ist der Monteur friend der Klasse Auto, damit er auf ihre privaten Attribute zugreifen kann.

    // Auto.h
    #ifndef AUTO_H
    #define AUTO_H
    
    #include <stdio.h>
    #include "Monteur.h"
    
    class Auto
    {
      friend class Monteur;
    
      private:
        int reifen, tueren;
    
      public:
        Auto()
        {
           reifen = 4;
           tueren = 4;
        }
    
        void print_tueren();
    };
    
    void Auto::print_tueren()
    {
      printf("%d\n", reifen);
    }
    
    #endif
    
    // Monteur.h
    #ifndef MONTEUR_H
    #define MONTEUR_H
    
    #include <stdio.h>
    #include "Auto.h"
    
    class Monteur
    {
      public:
        void print_reifen_des_zu_reparierenden_autos();
    };
    
    void Monteur::print_reifen_des_zu_reparierenden_autos()
    {
    	Auto *zu_reparierendes_auto;
    
    	printf("%d", zu_reparierendes_auto->reifen);
    }
    
    #endif
    

    Da ich vorher vom Compiler mit Errors erschlagen wurde, habe ich dafür auf Anrat Header-Guards eingebaut.

    Das Main-Programm soll jetzt einfach nur die Reifen des zu rep. Autos printen, es sollte also (wegen des Konstruktors) 4 ausgegeben werden.
    Stattdessen bekomme ich aber irritierende Fehlermeldungen:

    In file included from Auto.h:5,
    from AutoTest.cpp:1:
    Monteur.h: In member function 'void Monteur::print_reifen_des_zu_reparierenden_autos()':
    Monteur.h:15: error: 'Auto' was not declared in this scope
    Monteur.h:15: error: 'zu_reparierendes_auto' was not declared in this scope

    Kann mir jemand zeigen, wie der Code richtig aussehen müsste und zu verstehen geben, warum? 🙂



  • [center]EDIT[/center]
    Das Ganze rufe ich hiermit auf:

    #include "Auto.h"
    #include "Monteur.h"
    
    int main()
    {
    
    	//Auto *mein_auto = new Auto();
    	//mein_auto->print_tueren();
    
    	Monteur *monteur = new Monteur();
    	monteur->print_reifen_des_zu_reparierenden_autos();
    }
    

    (und ich werde mich jetzt registern, damit ich auch mal Posts editen kann x])



  • Lass das #include "Monteur.h" in auto.h mal weg.

    btw:
    Netter Titel. 😉



  • void Monteur::print_reifen_des_zu_reparierenden_autos()
    {
        Auto *zu_reparierendes_auto;
    
        printf("%d", zu_reparierendes_auto->reifen);
    }
    

    das wird sowieso nicht funktionieren, da der Zeiger "zu_reparierendes_auto" nicht initialisiert wurde.



  • @CppCoder: Behoben zu "Auto *zu_reparierendes_auto = new Auto();" .

    @drakon: Danke 😉
    Wenn ich es weglasse, funktioniert es komischerweise ... warum funktioniert es dann?
    Wenn ich "friend class Monteur;" schreibe, dann muss der Compiler doch die Klasse Monteur schon kennen, aber sie ist dann doch noch gar nicht definiert ... ? 😕



  • C-reator schrieb:

    Wenn ich "friend class Monteur;" schreibe, dann muss der Compiler doch die Klasse Monteur schon kennen

    Warum? Durch "friend class Monteur;" könnte er auch lernen, daß es diese Klasse überhaupt gibt und sich die Freundschaft schonmal merken.



  • C-reator schrieb:

    @drakon: Danke 😉
    Wenn ich es weglasse, funktioniert es komischerweise ... warum funktioniert es dann?
    Wenn ich "friend class Monteur;" schreibe, dann muss der Compiler doch die Klasse Monteur schon kennen, aber sie ist dann doch noch gar nicht definiert ... ? 😕

    Warum muss die Klasse wissen, wie die andere Implementiert ist? - Das interessiert die gar nicht. Sie (respektive der Compiler) muss nur wissen, dass diese Klasse auf die Internas zugreifen darf.

    EDIT:
    Definitionen sind grundsätzlich nur dann erforderlich, wenn die resultierende Grösse interessiert, respektive auf das Objekt zugegriffen wird. Das heisst bei:

    • Memberzugriff (inklusive kreierung)
    • Aggregierung
    • Vererbung
    • sizeof

    Nicht brauchen tust die Definition insbesondere bei:

    • Zeigern
    • Rückgabetypen
    • Parameter
    • friends
      ...


  • Zur Erklärung der Fehler noch der Hinweis, daß du sogenannte "Cross-Includes" benutzt hast (d.h. die beiden Header-Dateien "Auto.h" und "Monteur.h" binden sich gegenseitig ein). Durch die Include-Guards hast du zwar die Endlosrekursion vermieden, aber jetzt kennt die Monteur-Klasse die Auto-Klasse nicht mehr (oder umgekehrt, je nachdem welche Datei zuerst eingebunden wird).


Anmelden zum Antworten