Pointer Member anstatt Übergabe von KLassen?



  • Hallo,

    ich bin etwas unsicher was ssauberer ist bzw. was so in der regel gemacht wird.

    Angenommen ich habe mehrere Objekte (aus klasseninstanzen) myC1, myC2 etc....

    Jetzt habe ich eine dritte Klasse z.B. ClassFoo, die methoden hat die auf Objekten von myC2 und myC2 arbeitet, diese aber nicht verändert.

    Mir ist gerade "die Idee" gekommen anstatt in jeder Methode von ClassFoo die Objekte selbst bzw. pointer zu übergeben könnte ich doch innerhalb von ClassFoo member-pointer auf myC1 und myC2 anlegen und dann einfach lokal auf diesen arbeiten !? Ist das unsauber?

    Beispiel

    class ClassFoo
    {
        public:
            ClassFoo(MyC1* myC1, MyC2* myC2) 
             {
                   p_myC1 = myC1;
                   p_myC2 = myC2;
              }
    
              void foo() 
             {
                 //auf myC1 bzw. myC2 arbeiten aber über pointer p_myC1 und p_myC2
    
               }
    
        private:
            MyC1 *p_myC1;
            MyC2 *p_myC2;
    };
    
    //in der main
    MyC1 myC1 = new MyC1();
    MyC2 myC2 = new MyC2();
    
    ClassFoo myFoo = ClassFoo(myC1,myC2);
    myFoo.foo();
    


  • Nein, finde ich eigentlich gut. Allerdings was meinst du genau mit "nicht verändert"? - Wenn du wirklich z.B nur getter Methoden benutzt (welche ja const sind), dann kannst du const Zeiger speichern, anstatt normale.

    Kommt halt auch drauf an wie oft du damit rechnest, dass das andere Zeiger sind. Wenn es bei jedem Aufruf ev. andere Objekte sein könnten, dann wird das sicher hässlicher, aber ansonsten sollte das gut machbar sein.

    Ich würde ev. auch noch Methoden zum abfragen und setzen der Objekte selbst zur Verfügung zu stellen.



  • Du solltest dir auch über Besitzverhältnisse und anderweitige Nutzung deiner Objekte Gedanken machen.
    Wenn du sagen kannst "Meine Objekte gehören ClassFoo", dann würde ich keinen Konstruktor anbieten, der die Zeiger setzen kann, sondern nur Methoden die Zeiger oder besser Referenzen auf die Member zurückgeben.
    Dein Beispiel:

    //in der main
    MyC1 myC1 = new MyC1();
    MyC2 myC2 = new MyC2();
    
    ClassFoo myFoo = ClassFoo(myC1,myC2);
    myFoo.foo();
    

    legt dies nahe! Denn in der main würde ich niemals Objekte als Zeiger anlegen, denn gelöscht müssen die dann auch am Ende der main werden, per Hand!

    Wenn du aber Klassen von MyC1 und MyC2 ableitest und eben auch Objekte abgeleiteter Klassen in deinem ClassFoo haben willst, sind Zeiger die beste Möglichkeit (Referenzen würden auch gehen, sei dir aber über die Lebenszeit deiner Objekte hinter den Referenzen im klaren. Sind die tot (weil sie z.B. aus dem Scope laufen), stimmt deine Referenz nimmer.
    Auch kann eine Referenz nur einmal initialisiert und danach nimmer verändert werden (also ein anderes Objekt referenzieren).



  • Gafabi schrieb:

    //in der main
    MyC1 myC1 = new MyC1();
    MyC2 myC2 = new MyC2();
    
    ClassFoo myFoo = ClassFoo(myC1,myC2);
    myFoo.foo();
    

    Ich finde es nicht gut. Irgendjemand schreibt irgendwann mal so:

    //in der main
    MyC1 myC1 = new MyC1();
    MyC2 myC2 = new MyC2();
    
    ClassFoo myFoo = ClassFoo(myC1,myC2);
    delete myC1;
    myC1 = new MyC1;
    myFoo.foo();
    

    Und das Programm läuft manchmal, manchmal nicht...



  • danke für die ideen.

    was gäbe es dann für alternativen? Wirklich immer argumente übergeben?



  • hmm....hat sonst noch jemand eine Meinung?
    danke!



  • Und wie sieht es aus mit Pointer auf Objekte die ich innerhalb der klasse verändere? Wird die veränderung auch global gesetzt dann ausserhalb der klasse?



  • Gafabi schrieb:

    Und wie sieht es aus mit Pointer auf Objekte die ich innerhalb der klasse verändere? Wird die veränderung auch global gesetzt dann ausserhalb der klasse?

    Ja, klar. Du hast ja lediglich einen Zeiger auf einen Speicherbereich. Und wenn du den jetzt änderst ändert sich das für jeden, der auch auf diesen Bereich zugreift. Das ist ja unter anderem der Sinn von Zeigern.



  • abc.w schrieb:

    Gafabi schrieb:

    //in der main
    MyC1 myC1 = new MyC1();
    MyC2 myC2 = new MyC2();
    
    ClassFoo myFoo = ClassFoo(myC1,myC2);
    myFoo.foo();
    

    Ich finde es nicht gut. Irgendjemand schreibt irgendwann mal so:

    //in der main
    MyC1 myC1 = new MyC1();
    MyC2 myC2 = new MyC2();
    
    ClassFoo myFoo = ClassFoo(myC1,myC2);
    delete myC1;
    myC1 = new MyC1;
    myFoo.foo();
    

    Und das Programm läuft manchmal, manchmal nicht...

    Was ist hier das konkrete Problem? Insgesamt wäre der Quellcode doch korrekt und löst kein undefiniertes Verhalten aus, oder? (Es ist natürlich nicht schön, aber es tut das was ich hier lese: foo wird jetzt mit einem "anderen" myC1 aufgerufen?)



  • Doch es löst "Undefiniertes Verhalten" aus, denn die Klasse ClassFoo hat ja einen Zeiger auf den alten Speicherbereich erhalten (und keinen Zeiger-Zeiger)!


Anmelden zum Antworten