Keinen Pointer sondern das Array von Objekten übergeben



  • Hallo zusammen,

    ich möchte mich nochmals kurz - wahrscheinlich wieder für ein banales Problem - um eure Kritiken bemühen. Folgendes Beispiel wird behandelt:

    #include <iostream>
    #include <memory>
    using namespace std;
    
    class T
    {
        public:
        T() { cout << "create object\n"; };
        ~T() { cout << "destroy object\n"; };
    
        void setName( const string& n)  { name = n; };
        string getName() const { return name;};
    
        private:
    
            string name;
    };
    
    using p_T = unique_ptr<T[]>;
    
    void function1(p_T &t)
    {
        for (int i=0; i<10; i++) cout << t[i].getName() << "\n";
    };
    
    int main()
    {
        auto ptr_T = p_T (new T[10]);
    
        for (int i=0; i<10; i++) ptr_T[i].setName("12345678910" + i);
        for (int i=0; i<10; i++) cout << ptr_T[i].getName() << "\n";
    
        cout << "---- function ----\n";
        function1(ptr_T);
        cout << "---- function ----\n";
    
        for (int i=0; i<10; i++) cout << ptr_T[i].getName() << "\n";
    
        cout << "\n ................ end ................\n\n";
        return 0;
    }
    

    Kurze Erläuterung:

    • Die Klasse T ist wohl selbsterklärend
    • in Zeile 10 erstelle ich 10 Objekte der Klasse 10 und geb die Adresse des Arrays auf einen Pointer (unique_ptr), der für die Zerstörung der Objekte verantwortlich ist; somit muss ich das nicht mehr machen.
    • Ich initialisiere einige Werte, geb diese wieder aus um zu schauen ob alles funktioniert hat
    • Danach übergebe ich den Pointer als Referenz an die Funktion um dort die Ausgabe nochmals zu tätigen
    • Entsprechend nochmals die Ausgabe des Arrays um sicher zu sein das die Objekte noch existieren

    Letzter Punkt habe ich nur für mich eingefügt, weil ich den unique_ptr mit move() in die Funktion geschoben hab und dabei zerstört wurde (Gültigkeitsbereich). Ich denk für euch alles klar;

    Das funktioniert auch einwandfrei aber mir wurde nur nahe gelegt, anstatt den unique_ptr als Referenz, eine Referenz der Arrays auf den der unique_ptr zeigt, zu übergeben.

    Der Hinweis war folgender:

    void function1(T[] &t)
    {
       //Function...
    }
    
    function1(*ptr_T);
    

    Wie immer stellen sich folgene Fragen:

    • ist es schlechte Programmierung wenn man den unique_ptr übergibt, wie ich es in meinem Fall gemacht habe?
    • derzeit weiß ich nicht wie ich den Ansatz oben in das Programm einfließen lassen kann (also die Referenz auf das Array erhalte)

    Kritik und Hinweise sind erwünscht; eine Lösung muss nicht vorgestellt werden

    Viele Grüße
    Tobi


  • Mod

    Was ist denn hier das Ziel und wieso wird nicht vector benutzt?

    PS: Dir ist schon klar, dass es noch eine andere Methode gibt, Objekte der Klasse T zu erzeugen, außer dem Standardkonstruktor? Falls du dich mal wunderst, das mehr Objekte zerstört als erzeugt werden...



  • Hallo Sepp,

    danke für deine Rückmeldung.
    Ziel ist es etwas herumzutesten. »Nur« Lesen hat für mich persönlich nicht immer den Erfolg als wenn ich dann zusätzlich noch ein paar Beispiele angehe; ich möge jetzt viel Kritik erhalten aber: Buch + Try and Error find ich immer noch am Besten.

    Anstatt dem alten Array könnte ich natürlich den Container vector<T> verwenden, allerdings spielt das ja keine Rolle oder?

    Ziel ist es die Referenz des Arrays zu übergeben und nicht den Pointer selber.
    Wenn es immer noch nicht klar ist bitte um nochmalige Rückmeldung.

    Grüße
    Tobi



  • Shor-ty schrieb:

    Ziel ist es etwas herumzutesten. »Nur« Lesen hat für mich persönlich nicht immer den Erfolg als wenn ich dann zusätzlich noch ein paar Beispiele angehe; ich möge jetzt viel Kritik erhalten aber: Buch + Try and Error find ich immer noch am Besten.

    Das ist ein vernünftiger Ansatz.

    Shor-ty schrieb:

    Anstatt dem alten Array könnte ich natürlich den Container vector<T> verwenden, allerdings spielt das ja keine Rolle oder?

    Naja, den Vector würde man natürlich ohne unique_ptr verwenden.

    Shor-ty schrieb:

    Ziel ist es die Referenz des Arrays zu übergeben und nicht den Pointer selber.

    p_T.get() liefert den Inhalt des unique_ptr.



  • Hallo,

    danke für deine Rückmeldung.
    Ich habe erst gehört das man einen Vektor auch so definieren kann:

    std::vector<unique_ptr<T>> vec[10];
    

    Ist das sinnvoller als:

    std::vector<T> vec[10];
    

    Ich dachte nämlich das die Klasse Vektor die Objekte und deren Zerstörung auch behandelt.



  • Shor-ty schrieb:

    Ich habe erst gehört das man einen Vektor auch so definieren kann:

    std::vector<unique_ptr<T>> vec[10];
    

    Das ist ein Array von Vectoren von unique_ptr von T.

    Shor-ty schrieb:

    Ist das sinnvoller als:

    std::vector<T> vec[10];
    

    Das ist ein Array von Vectoren von T.

    Shor-ty schrieb:

    Ich dachte nämlich das die Klasse Vektor die Objekte und deren Zerstörung auch behandelt.

    Das wäre

    std::vector<T> vec;
    

  • Mod

    std::vector<unique_ptr<T>> vec;
    

    vector stellt bestimmte Anforderungen an seinen Elementtyp. Manchmal genügt das T diesen Ansprüchen aber nicht, ein unique_ptr<T> dagegen schon. Beispielsweise:
    - Der gespeicherten Elemente eines vector müssen exakt den deklarierten Typ haben, manchmal möchte man aber mit Polymorphie arbeiten.
    - vector erwartet, dass seine Elemente kopierbar oder verschiebbar sind. Das ist nicht bei allen Typen der Fall oder zumindest gelegentlich zu teuer. Manchmal benötigt man auch einfach nur stabile Verweise auf Objekte.


Log in to reply