Zugriff auf ein Methode einer anderen Klasse



  • Folgendes Problem habe ich: (schwer zu beschreiben)

    Ich muss für die Schule ein sehr einfaches Schachprogramm programmieren.

    Mit folgendem Konzept habe ich begonnen das Programm zu implementieren.

    Mein Schachprogramm besitzt eine Klasse Figur. Von dieser Klasse erben alle Figuren also Springer, Turm, Dame, ....
    Die Figuren enthalten als Eigenschaft die Farbe, alle Möglichen Zugmöglichkeiten (Eigenschaft?!?) ...
    Außerdem habe ich eine Klasse Schachbrett. Hier wird alles verwaltet wie z.B. Zeit, Notation. In dieser Klasse sind alle Figuren eingebettet. Also hier wird festgehalten
    wo die Figuren sitzen.

    Mein Problem ist, dass die Klasse Figur zugriff auf die Klasse Schachbrett benötigt, um die Zugmöglichkeiten zu ermitteln (Sie muss wissen wo die Figuren sitzen)
    und diesen Zugriff bringe ich nicht hin.

    Also hier das Problem: (sieht etwas seltsam aus weil ich fast alle Methoden/eigenschaften entfernt habe - also schreibt nichts über den Stil)

    hier die Klasse Figur:

    #include <stdio.h>
    
    //#include "schachbrett.h" geht nicht weiß nicht warum
    
    class figur
    {
       private:
    
         int iwert;
    
       public:
    
         void zugriff (void)
         {
            ;// printf("%c",test());
            //benötige Zugriff auf Schachbrett auf die Methode test
         };
    
         virtual char welche_figur (void){return 'f';};
    
         figur(){;};
    };
    

    hier der Turm der von der klasse Figur erbt

    class turm  : public figur
    {
       public:
          turm(){;};
          char welche_figur (void){return 't';};
    };
    

    und dann noch die klasse Schachbrett

    class schachbrett
    {
       private:
    
          figur *feld[8][8];
          turm t1;  //eingebettete Figuren
    
       public:
    
          schachbrett()
          {
            feld[0][0] = &t1;
          };
    
          char test (void)
          {
            return feld[0][0]->welche_figur();
            //die Klasse Figur soll auf diese Methode Zugriff haben
          }
    };
    

    könnt ihr mir bitte helfen !!! Kann jemand den Quelltext so umformen, dass die Methode Zugriff auf test zugreifen kann!
    ich verzweifle noch.

    Dieses Problem hält mich jetzt schon lange auf. Mein Lehrer konnte mir auch nicht so leicht weiterhelfen, da das Programm jetzt schon ziemlich groß ist.

    PS.: die Lösung am besten ohne friend



  • Ich muss für die Schule ein sehr einfaches Schachprogramm programmieren.

    Auf was für einer Schule bist du denn?

    Ich bin mir nicht sicher, aber könnte dir das Visitor Pattern evtl. weiterhelfen?
    http://www.cuj.com/documents/s=8467/cujjsup1906martin/#1



  • Ich gehe auf das Informations Technische Gymnasium. (Profilfach IT)

    Zudem eine Hilfe auf Deutsch wäre mir lieber. Englisch ist naja.



  • Ich glaube, dass funzt net, weil du keine Instanz von schabrett angelegt hast. Woher soll denn dein der Compiler wissen, dass sich dein Funktionsaufruf "test()" in Zugriff auf eine Methode der Schachbrett-Klasse bezieht ?
    Du könntest vielleicht in der Klasse Figur eine static-Instanz von Schachbrett aufnehmen. Das Schachbrett ist ja sowieso für alle Figuren dasselbe, von daher funzt das vielleicht so:

    /*andere Includes...*/
    #include "schachbrett.h" /*Müsste eigentlich gehen; viell. hast du in Schachbrett.h irgendwelche Def. und inkludierst die Datei mehrfach ???*/
    
    class figur
    {
       private:
         static schachbrett Brett;  //Muss dann irgendwo initialisiert werden...
    
         int iwert;
    
       public:
    
         void zugriff (void)
         {
             printf("%c",Brett.test()); /*Warum eigentlich printf ? Willst du nicht iostream benutzen ? Wäre C++-typischer */
          };
    
         virtual char welche_figur (void){return 'f';};
    
         figur(){;};
    };
    

    Bin mir da aber nicht sicher, ob's so klappt, aber der Ansatz erscheint mir logisch.
    Gruß
    E-the-Real



  • Ich denke das Problem mit dem includieren liegt daran, dass die Klasse Figur und die Klasse Turm in der Klasse Schachbrett schon eingebettet ist.

    also diese Klasse Schachbrett sieht so aus:

    #include "figur.h"  //Klasse Figur ????
    #include "turm.h"
    
    class schachbrett 
    { 
       private: 
    
          figur *feld[8][8]; 
          turm t1;  //eingebettete Figuren
    //...
    

    vielleicht gibt es damit Probleme. Zu tief oder "im Kreis" verschachtelt.
    Könnte das sein ?
    Wenn ja wie kann man es umgehen. Dein Ansatz könnte klappen, aber dann muss ich erst das include Problem beseitigen.



  • Ich persönlich würde z.B. die Funktionsdefinitionen erstmal in cpp.-Dateien auslagern, so dass ich in der Klasse nur Deklarationen hab. Dann kannst du noch probieren, die Header-Dateien vor mehrfachen inkludieren zu schützen, in dem du ihnen eine Define-gebundene Abfrage voranstellst, das heisst konkret:

    //z.b. figur.h
    #ifndef __FIGUR_INCLUDED__
    #define __FIGUR_INCLUDED__
    
    /* hier stehen deine ganzen Deklarationen ...*/ 
    
    #endif __FIGUR_INCLUDED__
    

    Dazu kannst du mal in die FAQ schauen, ich glaub, da steht was dazu drin...
    Übrigens fällt mir gerade auf: In der Datei "figur.h" inkludierst du "schachbrett.h", die wiederum u.a. "figur.h" inkludiert. Das ist in der Tat etwas merkwürdig.
    Aber ich bin jetzt etwas überfragt, wie deine Header-Verankerung genau ausschaut, vielleicht kann man das eleganter lösen...???
    Gruß
    E-the-Real



  • ethereal schrieb:

    //z.b. figur.h
    #ifndef __FIGUR_INCLUDED__
    #define __FIGUR_INCLUDED__
    
    /* hier stehen deine ganzen Deklarationen ...*/ 
    
    #endif __FIGUR_INCLUDED__
    

    Wie so oft: Man darf niemals globale Bezeichner verwenden, die mit einem Unterstrich beginnen. ⚠
    Diese sind ausschließlich den Compilerbauern vorbehalten.

    Lass die Unterstriche einfach weg, die erfüllen da eh keinen Zweck.



  • Echt ? Oha, das ist mir neu, danke für die Aufklärung. Ist das denn offiziell so geregelt ?
    Naja,dann halt ohne Unterstrich...



  • Leider hilft es auch nichts wenn ich diese Präprozessor Direktiven vor die includs stelle.

    und in meinem programm habe ich es getrennt *.cpp und *.h nur wäre das schlecht zum posten gewesen.

    Ich kann dieses Problem einfach nicht lösen.

    Kann jemand ***bitte*** einmal seinen Borland anwerfen. Eine Konsolenanwendung starten, drei weitere Units einfügen. In diese Unit dann meinem Quellcode kopieren und dann zum laufen bringen und dann wieder posten.

    Ich denke es wird für einen sehr guten programmierer keine allzu lange Aufgabe sein, oder ?

    Um dieses Problem wäre es besten wenn ihr es versucht mit einer Refernz, da ich es schon so begonnen habe zu implementieren.
    also mit

    Schachbrett &brett;
    

    BITTE --- BITTE --- BITTE --- BITTE --- BITTE



  • Leg doch einfach mal ein Schachbrett an.

    Schachbrett dasBrett;

    und jetzt kannst Du von überall drauf zugreifen, einfach mit dasBrett.meineMethode();

    So, und jetzt überfallt mich, weil das eine globale Variable ist.
    Aber zunächst bitte bedenkt zwei Sachen:

    1)Gibt's was globaleres als ein Schachbrett in einem Schachprogramm? Warum also nicht global machen.

    1. Ein Singleton wäre wohl für den Anfang etwas verwirrend.


  • außerdem wär es cool, wenn man auf mehreren Schachbrettern gleichzeitig spielen könnte -> kein Singleton 😃 😉
    gelaoescht



  • Danke
    So funkt es !! Ich habe ein globale Instanz in unit1 erueugt.

    Aber der Linker bringt immer folgende Warnung:

    [Linker Warnung] Public symbol '_brett' defined in both module C:\...\UNIT1.OBJ and
    C:\...\FIGUR.OBJ

    Was bedeutet diese Warnung ?

    Meiner Meinung nach ist es aber keine saubere Lösung eine globale Instanz. Das kann man doch sicher anders lösen ??? (Mein Leher mag globale Sachen nicht)

    Könnte das jemand mal anders lösen, bitte!
    evtl gerade mit einer Referenz, so dass es funktioniert.



  • Also für den Anfang würd ich das Brett erstmal global lassen... es ist in einem Schachspiel (zumindest in einem einfachen) ja erstmal global. Also warum nicht global modellieren.

    Den Linkerfehler kriegst Du, weil Du das Brett in der Header-Datei anlegst. Du mußt es in einer cpp-Datei anlegen. Und in die Headerdatei kommt nur die Deklaration:

    extern Schachbrett dasBrett;

    und in die Implementierung dann:
    Schachbrett dasBrett;

    Das sollte vorerst mal genügen.

    MfG Jester



  • und wenn du globale Variablen umbedingt umgehen willst, dann informier dich über das Singleton Pattern - das bewirkt im großen und ganzen das Gleiche wie eine globale Variable, ist aber eleganter und wird wohl auch deinem Lehrer besser gefallen 😉

    Aber eigentlich tut's auch eine globale Variable...

    Mfg, smasher1985



  • Das gleiche Problem etwas allgemeiner haben wir hier:

    http://www.c-plusplus.net/forum/viewtopic.php?t=65858



  • Das versteh ich nicht ganz mit der Fehlermeldung. Ich habe die Instanz in einer cpp Datei erzeugt.

    Also in meiner Konsolenanwendung (vorerst) habe ich die Inanz in der Unit1.cpp erzeugt.

    Das sieht so aus:

    #include "schachbrett.h"
    
    schachbrett brett;
    
    int main(int argc, char* argv[])
    {
            brett.ausgabe();
            getch();
            return 0;
    }
    

    Ich mache sie halt jetzt global. Was solls. Widerspricht sich halt mit der Kapselung, aber einmal kann man darüber hin wegschauen.
    Aber könnt ihr mir bittet nochmal helfen bei dieser Fehlermeldung.

    Danke



  • Hallo!

    Ich glaube ich habe lösung für Dein Problem. Anstatt Datei mit dem Definition der Klasse Schachbrett zu includieren solltest Du class Schachbrett; angeben!
    Damit teilst Du den Compeiler mit daß Du die Klasse benutzen will und daß die irgendwo schon declariert ist. Und dann sollte Deine metode Zugriff() einen Parameter übernehmen, ein Referenz auf Schachbrett Objekt: void Zugriff(Schachbrett& brett){ printf("%c", brett.test())}. Dann kannst Du in main cpp Datei ganz normal die Dateien includieren, Objekte von Schachbrett und Figur erzeugen, und deine Metoden aufrufen! Habe ein großes Respekt von Dir! Ich meine so ein Schachprogramm zu schreiben ist meine ansicht nach unendlich schwere Aufgabe! Will mal gerne ganze Programm sehen!
    Grüß Denis.



  • Mir fällt auch noch eine Möglichkeit ein, und zwar folgende ( friends )

    class A;   // Vorwärts-Deklaration
    class B
    
    {
      void m(A _a);
    };
    
    class A
    {
    private:
      int i;
    
    public:
      void init();
      friend void B::m(A _a);
      friend void f(A _a, int i);
      friend class C;
    };
    

Anmelden zum Antworten