Klasse an Klasse übergeben



  • Hallo SeppJ,

    wenn das so funktioniert dann JA.......
    Ich hätts halt schöner gefunden wenn man eine Klasse B erzeugt und ihr dann ein für allemal eine Instanz der Klasse A übergibt....
    Und nicht jeder Moethode einzeln..... Aber ok....

    Sowas wär für mich geil....

    class A
    {
     // Members usw.
    };
    
    class B(A Instanz_1) // das ich die Instanz einer Klasse gleich bei der
    {                    // Definition der Klasse übergebe.
    
    public:
    //Methoden usw.
    
    };
    

    Aber so mag der Kompiler irgendwie nicht.....
    Ok, ich werds probieren.....
    falls es noch was geschickteres gibt wär ich dankbar....

    Ansonsten ists so auch gut....

    Danke soweit

    mfg Ishi131


  • Mod

    Klar das kannst du auch machen. Gib der Klasse B eine Referenz oder einen Zeiger auf dein A Objekt. Und guck dir mal an, was ein Konstruktor ist.



  • ETA: damit das funzt müssen allerdings die Members von A public sein (oder du haust noch ein "friend B;" rein)

    class B
    {
    public:
     A* m_A;
     B(A* a) : m_A(a);
    private:
     B(); // nur damit keiner auf die Idee kommt ein B ohne den Verweis auf A zu instanziieren
    bool Manip_2(){a->i[0]=5};
    }
    
    A* A1 = new A;
    B B1(A1);
    B B2(A1);
    

    nichts chön, aber selten.... Problem ist wenn du A1 deletest und weiterhin versuchst mit B1, B2 zu arbeiten. Dann gibts Ärger.



  • Hallo,

    danke für die schnelle Antwort.....
    Ich glaub wir sind der Sache schon ziemlich nahe....
    Mim Deleten wirds keine Probleme geben weil A1, B1 und B2 alle gleich lang "leben".

    Was ich jetzt noch fragen wollte ist ob du mir die eine Zeile erklären könntest.

    B(A* a) : m_A(a);
    

    Da versteh ich nicht was das bedeutet....
    Ich übergebe der Klasse B einen Pointer auf A....Das macht ja Sinn.... Aber das danach???

    @ SeppJ:
    Ich weiß zwar was ein Konstruktor ist, aber wenn ich dem die Instanz A1 übergebe kennen die anderen Methoden von B die Instanz A1 immer noch nicht.

    So hab ichs ja schon probiert....

    Mfg Ishi1313



  • antialias schrieb:

    ETA: damit das funzt müssen allerdings die Members von A public sein (oder du haust noch ein "friend B;" rein)

    class B
    {
    public:
     A* m_A;
     B(A* a) : m_A(a);
    private:
     B(); // nur damit keiner auf die Idee kommt ein B ohne den Verweis auf A zu instanziieren
    bool Manip_2(){a->i[0]=5};
    }
    
    A* A1 = new A;
    B B1(A1);
    B B2(A1);
    

    nichts chön, aber selten.... Problem ist wenn du A1 deletest und weiterhin versuchst mit B1, B2 zu arbeiten. Dann gibts Ärger.

    Oder er lässt die privat in A und erstellt Funktionen um die Daten zu manipulieren, über diese Schnittstelle kann dann B die Daten verändern.
    Bei vielen Funktionen wär dann aber vll doch eine friend Deklaration angebracht um die Daten direkt zu verändern.

    Ist irgendwie sehr ähnlich 😉
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-274498.html

    Lg freeG


  • Mod

    Ishi1313 schrieb:

    @ SeppJ:
    Ich weiß zwar was ein Konstruktor ist, aber wenn ich dem die Instanz A1 übergebe kennen die anderen Methoden von B die Instanz A1 immer noch nicht.

    Anscheinend weißt du nicht viel über Konstruktoren, sonst hättest du antialias geheimnisvolle Zeile als eben genau diesen erkannt. Sie macht auch genau das was ich beschrieben habe. Du solltest unbedingt noch mehr über solche Grundlagen lernen, bevor du so komplizierte Konstrukte bastelst.

    Aber ich muss vorher noch sagen: Dein Design ist ganz schwerwiegend faul. Überdenke dies unbedingt. was du hier vor hast sind sehr ungewöhnliche Konstruktionen bei denen ganz ganz leicht schwer zu findende Fehler auftreten können (und werden).



  • Was ich jetzt noch fragen wollte ist ob du mir die eine Zeile erklären könntest.

    B(A* a) : m_A(a);
    

    Da versteh ich nicht was das bedeutet....

    das ist ein Konstruktor (mit einem Parameter: dem Pointer auf ein Objekt von Typ A). Das hinter dem Dopplepunkt ist eine Initialisierungsliste. Der Membervariable m_A wird der Wert von a zugewiesen.

    ist effektiv das selbe wie

    B(A* a)
    {m_A = a;}
    

    Initialisierungslisten haben allerdings ein paar Vorteile was Performance angeht - aber ich glaube bei einer Initialisierung eines Pointers macht das keinen Unterschied (oder? weiss das jemand zufällig sicher?)



  • antialias schrieb:

    class B
    {
    public:
     A* m_A;
     B(A* a) : m_A(a);
    private:
     B(); // nur damit keiner auf die Idee kommt ein B ohne
          // den Verweis auf A zu instanziieren
     bool Manip_2(){a->i[0]=5};
    }
    

    Die Deklaration des Default-Konstruktors ist in diesem Fall überflüssig, wenn er sowieso nicht benutzt werden soll. Du hast ja schon B::B(A*) deklariert. Damit verhinderst Du schon die automatische Erzeugung eines Default-Konstruktors. Der Konstruktor B::B(A*) sollte vielleicht auch explizit sein.



  • Ok,

    Danke soweit.....
    Ich werd jetzt erstmal darüber nachdenken..und ein Buch holen.... Gegebenenfalls meld ich mich nochmal...

    Danke

    Ishi131



  • Hallo die Herrschaften,

    hab das mir gestern nochmal gut angeschaut und (glaub ich) verstanden....

    Jetzt ist die Sache das ihr schon recht habt.... Das ist nicht grad schön.....

    Daher meine Frage:
    Wie kann man von einer Klasse 2 Instanzen erzeugen sodass sich die 2 Instanzen einige Members teilen, andere Members allerdings getrennt sind.

    Gibts da was???

    Was ich mir jetzt bisher gedacht habe wäre:

    Ich mach mir ne Klasse A:

    class A
    {
    public:
    int i[5];
    bool j[10];
    };
    

    dann ne Klasse B:

    class B
    {
    private:
    int i2[5];
    bool j2[10];
    public:
    int i3[5];
    bool j3[10];
    void manipulate();
    };
    

    und schlussendlich ne Klasse C der mit der Zusammenfassung......

    class C
    {
    private:
    A Instanz_A;
    public:
    B Instanz_B1;
    B Instanz_B2;
    C(A* p_A, B* p_B1, B* p_B2)   // Konstrktor
    void manipulate2();
    };
    

    Wäre das jetzt ein besserer Stil????

    Man erzeugt sich ja ne Instanz der Klasse A --->nämlich A1
    Man erzeugt sich ja 2 Instanzen der Klasse B --->nämlich B1 & B2;
    Diese 3 Instanzen übergibt man dann dem Konstruktor einer Instanz von Klasse C.
    Jetzt haben ja dann die Instanzen B1 und B2 sozusagen einen gleichen Speicher auf den sie zugreifen nämlich:

    int i2[5];
    bool j2[10];
    

    und zusätzlich hat jede Instanz seinen eingenen privat & public Speicher

    int i2[5];
    bool j2[10];
    

    ist das so eine saubere Lösung???
    Oder gehts noch besser??

    Mfg Ishi131



  • Hey,

    kann es sein das sich mein Problem ganz einfach mit

    class A{
    static i[5];
    static bool j[5];}
    

    lösen läßt.......
    Sind dann für alle Instanzen von A die Werte im Array gleich????

    Mfg.....


  • Mod

    Ja.

    edit: Soweit jedenfalls die Bedeutung von static. Ob das wirklich ein gutes Design für dein Problem ist, ist eine andere Frage. Häufig deutet static nämlich eher auf nicht so gutes Design hin. Ganz besonders wenn alle Member static sind. Aber ich mag jetzt nicht 2 Seiten Thread durchlesen um deine Problemstellung zu suchen.



  • Dank dir Seppl.....

    Hahahhahahaha. manchmal gehts ganz einfach...

    lg


  • Mod

    Ich habe oben noch was reineditiert, was du lesen solltest. Habe zu spät gesehen, dass du bereits geantwortet hast.



  • jetzt hasts editiert in der Zeit wo ich geschrieben hab.....

    Wie soll ich es sonst machen????

    So wie oben beschrieben????


  • Mod

    Ishi... schrieb:

    jetzt hasts editiert in der Zeit wo ich geschrieben hab.....

    Wie soll ich es sonst machen????

    So wie oben beschrieben????

    Schilder mal dein konkretes Problem (falls möglich), es gibt sicherlich eine elegantere Modellierung.



  • Ok,

    als kleine Vorbemerkung benutz ich grad die Qt Klasse.........

    also ich habe mir eine Klasse "Bild" gemacht/designed über die ich ein Bild laden kann.
    Wenn ich eine Instanz dieser Klasse erzeuge wird das Bild am Bildschirm angezeigt.

    Ich erstelle mir genau 2 Instanzen dieser Klasse und lasse mir somit 2 Bilder nebeneinander anzeigen.

    Die 2 Bilder sind FAST identisch. Sie unterscheiden sich aber in 5 Punkten.
    Aufgabe des Spielers ist, mit der Maus auf diese 5 Punkte zu klicken und somit die Fehler zu finden..... Dabei ist egal, auf welchem Bild er den Fehler anklickt.
    Wenn man einen Fehler findet und diesen anklickt, wird in der Klasse "Bild" das entsprechende bool Element auf "true" gesetzt was so viel bedeutet als das der Fehler gefunden wurde.

    Wenn ich aber diese "bool- Elemente" in der "Bild-Klasse" habe, erzeugt er mir für jede Bild-Instanz soche "bool-Elemente" und dann hab ich auf einmal 10 Fehler anstatt bloß 5 weil er unterscheidet auf welchem Bild ich den Fehler gefunden habe.Und genau das will ich nicht...

    Ich will das beide Bilder auf genau die gleichen bool Elemente zugreifen

    Hoffe das war verstaendlich....

    lg

    Ishikura


  • Mod

    Du hast also 2 Bilder und 5 Fehler, welche quasi dein Spielfeld ausmachen. Lösung: Mach eine Klasse Spielfeld. Diese enthält 2 Bilder und 5 Fehler.



  • Jo, hab ich mir auch schon überlegt.....
    Aber dann hat das mit der Maus-Position ermitteln nicht mehr hin.....
    Das gilt ja dann fürs komplette Spielfeld und ich wills ja NUR für jedes Bild...
    Oder ich bin zu blöd das gescheit einzustellen..... Könnte ich nochmal gucken...
    Ich probiers so wie du gesagt hast, wenn nicht mit static, und wenn das fehlschlägt meld ich mich nochmal....
    merci Ishi131



  • SeppJs Vorschlag und deine Bedenken sind durchaus vereinbar.
    Deine Bildklasse hat ja die Punkte und kann feststellen ob einer der Punkte angeklickt wurde. Das kannst du ja so beibehalten.
    Was du jetzt beispielsweie anders machen könntest wäre das ganze boolzeugs aus der Bildklasse rauszunehmen und die Spielklasse einfach darüber zu informieren das ein Punkt geklickt wurde und auch welcher. Diese Informatione kannst du dann beispielsweise in einer Liste speichern. Sollte ein Punkt der zurückgegeben wird bereits in der Liste vorhanden sein ist kein neuer Fehler aufgedeckt worden.

    Wie du das machst ist dann ersteinmal egal. Beispielsweise könntest du ein Ereignis auslösen das die Spieklasse fängt oder du sendest ein QT-Signal deiner Bildklasse das einen Slot der Spielkasse auslöst.
    Alternativ kannst du deinen Bildkalssen auch ein Zeiger auf das verwaltende Objekt übergeben.

    Aber egal, worauf ich hinaus möchte ist, dass du in deinem Bild prüfst ob ein relevanter Punkt geklickt wurde. Ob das nun jedoch ein Fehler ist oder nicht lässt du andere entscheiden.


Anmelden zum Antworten