Klasse an Klasse übergeben



  • Hallo miteinander,

    ich hab grad ein bisschen ein "Klassen-Problem".

    Ich möchte das ganze an einem kleinen Beispiel erklären damit die Sache hoffentlich verständlich wird. Ist wohl keine großes Problem für Könner aber ich weiß nicht mal wo ich nach Antworten suchen soll weil ich keinen Anhaltspunkt habe.

    So, Ich habe eine Klasse A

    class A
    {
    private:
    int i[10];
    bool w[10];
    };
    

    Von dieser Klasse erzeuge ich NUR GENAU 1 Instanz .

    A A1;
    

    Die Klasse "class A" enthält auch nur Member (Nur die 2 Arrays). Methoden enthält Klasse A NICHT.

    Jetzt gibt es aber noch eine Klasse B.

    class B
    {
    private:
    int i;
    // Usw.
    
    public
    B();
    bool Manip_2();
    // Usw.
    
    };
    

    Von der Klasse B "class B" erzeuge ich mir 2 Instanzen ,

    B B1, B2;
    

    wobei jede Instanz unterschiedliche Members besitzt. ( Klasse B wird von einer anderen Klasse vererbt [B ist sozusagen ein Kind von QWidget aus der Qt-Klasse]...... Aber ich glaube das interessiert an dieser Stelle nicht.

    Mein PROBLEM ist jetzt das die Methoden der Instanzen "B1" und "B2" teilweise auf Members der Instanz A1 zugreifen. Und so wie ich das bisher machte "erkennen" die Moethoden der Klasse B1 und B2 die Members der Instanz A1 nicht.
    Wie bekomme ich das hin? Gibt es da einen Trick? Das gibts doch nicht das sowas nicht möglich ist.... Ich steh auf dem Schlauch....
    Kann ich beiden Instanzen von B ( B1 und B2) eine Instanz der Klasse A (A1) übergeben sodass beide auf A1 zugreifen kann?

    Für eine Antwort oder einem Stickwort womit ich Suchen kann wäre ich dankbar.

    Mfg Casicas


  • Mod

    Du kannst Klasseninstanzen (also Objekte) so übergeben wie die primitiven Datentypen auch:

    class A
    {
     // Member von A
    };
    
    class B
    {
    public:
     bool Manip_2(A);
    }; 
    
    bool B::Manip_2(A a)
    {
     // Mach irgendwas mit a. Natürlich kein Zugriff auf privates.
    }
    
    int main()
    {
     A a1;
     B b1;
     b1.Manip_2(a1);
    }
    

    Ist es das was du meintest?



  • 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.


Anmelden zum Antworten