Durch Funktion Inhalt eines Objektes kopieren



  • Hallo

    Ich hab mal eine allgemeine Frage.

    Wir haben als Aufgabe von unserem Prof eine Zeigerablage mit Klassen und Objekten zu realisieren.
    Ist auch kein Thema. Allerdings gibt es eine Nebenaufgabe, in der verlangt er zwei Methoden zum auffinden des minimums und maximums der Ablage. Dafür soll eine Funktion geschrieben werden, mit der wir den Inhalt des Objekts in ein 2tes Objekt zur zwischenablage kopieren sollen. Wir dürfen dafür (also für das kopieren) keine Methode verwenden. Und damit hab ich ein Problem. Ich versteh auch den Sinn nicht. Mit ner Methode wäre es doch super easy.

    Meine Frage: Geht das überhaupt?
    Der Punkt ist, dass ich auf die Inhalte der Klasse ja nicht von außen zugreifen kann, weil sie pivate sind. Wie soll denn das gehen?

    Danke für eure Antworten

    Grüße



  • (Pseudo-)Code?
    Ich kann mir da grad nix drunter vorstellen oO



  • Ich kann dir auch meinen bisherigen richtigen Code geben:

    Das hier ist die Klasse:

    class knoten{
    
    private:
    
        int i;
        int info;
        class knoten*next;
    
    public:
    
        void initalize(){
            class knoten*p=new knoten;
    
            cnt++;
            p->i=cnt;
            p->info = rand()%100;
            p->next = oben;
            oben=p;
    
        }
    
        void drauflegen(){
            class knoten*p=new knoten;
            cnt++;
            p->i=cnt;
            p->info = rand()%100;
            p->next = oben;
            oben=p;
            cout << "Wert draufgelegt!" << endl;
        }
    
        void top(){
            cout << "Oberer Knoten (Nr. " << oben->i << "): ";
            cout << oben->info << endl;
        }
    
        void max() {
    
        }
    
        void min() {
        }
    };
    

    Und hier die Main:

    int main() {
    
        knoten ablage1, hilfsablage;
        int eingabe=1;
        int max, knotennummer;
    
        ablage1.initalize();
    
        cout << "-----------Menü-----------" <<endl;
        cout << endl;
        cout << "1        Objekt drauflegen" <<endl;
        cout << "2     oberen Wert anzeigen" <<endl;
        cout << "3           Maximum suchen" <<endl;
        cout << "4           Minimum suchen" <<endl;
        cout << "5   Anzahl Knoten anzeigen" <<endl;
        cout << "0                  Beenden" <<endl;
    
        while(eingabe!=0){
            cout << "Ihre eingabe: ";
            cin >> eingabe;
            cout << endl;
            switch (eingabe){
    
                case 1: 
                    ablage1.drauflegen();
                    break;
    
                case 2:
                    ablage1.top();
                    break;
    
                case 3: 
                    hilfsablage=ablage1;
                    hilfsablage.max();
                    break;
    
                case 4: 
                    hilfsablage=ablage1;
                    hilfsablage.min();
                    break;
    
                case 5:
                    cout << "Anzahl Daten: " << cnt <<endl;
                    break;
    
                case 0: 
                    break;
            }
        }
    
        return 0;
    }
    

    Aber meine Frage ist ja eher allgemein, wie man ein Objekt mit einer Funktion kopieren soll. Ich kann ja nicht auf die Internen variablen des Objekts zugreifen weil sie privat sind. Das geht doch nur mit einer Methode oder nicht?



  • Sofern Du auch keinen Kopierkonstruktor oder einen überladenen Zuweisungsoperator benutzen darfst, könntest Du eine Funktion als friend deklarieren. Die darf dann auch auf private - Elemente zugreifen.



  • Ohne die genauen Anforderungen der Klasse Ablage zu kennen könnte man auch Zugriff auf jedes Element erlauben und eine Methode anbieten, die die Anzahl der Elemente zurückliefert. min und max iterieren dann über die einzelnen Elemente und liefern das kleinste bzw. größte Element zurück.
    Die Lösung mit Chromleisten wäre dann die Implementation von Iteratoren, damit könntest du Algorithmen und Daten vollständig voneinander trennen. Ist für einen Uni-Programmierkurs aber wohl viel zu viel verlangt.

    PS:
    Das Schlüsselwort class bei der Variablendeklaration/-definition brauchst du nicht.

    knoten* p = new knoten();
    

    Die Aufgabe scheint wohl zu sein, eine einfach verkettete Liste oder Stack zu implementieren. Du benutzt dabei nur die Klasse Knoten, die abhängig von ihrer Verwendung mal die Listen oder einen Knoten der Liste repräsentiert. Die korrekte Beziehung von Knoten und Liste ist nicht "List-ist-Knoten", sondern "Liste-ist-implementiert-durch-Knoten". In letzterem Fall ist Komposition das richtige Modell (oder nonpublic Inheritance). Die Liste sollte also in etwa so aussehen:

    class List
    {
       knoten* head;
    
       void drauflegen( int i )
       {
          knoten p = new knoten();
          p->i = i;
    
          p->next = head;
          head = p;
       }
    
       // usw...
    };
    

    Bitte beachte, dass du die Regel der Drei (Fünf) beachten musst, da beim Kopieren der Liste nicht einfach den Zeiger des Listenkopfes kopieren darfst, sondern die Liste komplett kopieren musst.

    Und dein bisher "richtiger" Code ist, so leid es mir tut, fürchterlich. Er lädt geradezu ein, Objekte falsch zu gebrauchen und entweder Speicherlecks oder undefiniertes Verhalten durch doppeltes delete zu erzeugen.



  • Von Iteratoren oder friend funktionen hab ich allerdings noch nie was gehört^^



  • Cabooze schrieb:

    Von Iteratoren oder friend funktionen hab ich allerdings noch nie was gehört^^

    Macht nix, gibt ja google.



  • DocShoe schrieb:

    Ohne die genauen Anforderungen der Klasse Ablage zu kennen könnte man auch Zugriff auf jedes Element erlauben und eine Methode anbieten, die die Anzahl der Elemente zurückliefert. min und max iterieren dann über die einzelnen Elemente und liefern das kleinste bzw. größte Element zurück.
    Die Lösung mit Chromleisten wäre dann die Implementation von Iteratoren, damit könntest du Algorithmen und Daten vollständig voneinander trennen. Ist für einen Uni-Programmierkurs aber wohl viel zu viel verlangt.

    PS:
    Das Schlüsselwort class bei der Variablendeklaration/-definition brauchst du nicht.

    knoten* p = new knoten();
    

    Die Aufgabe scheint wohl zu sein, eine einfach verkettete Liste oder Stack zu implementieren. Du benutzt dabei nur die Klasse Knoten, die abhängig von ihrer Verwendung mal die Listen oder einen Knoten der Liste repräsentiert. Die korrekte Beziehung von Knoten und Liste ist nicht "List-ist-Knoten", sondern "Liste-ist-implementiert-durch-Knoten". In letzterem Fall ist Komposition das richtige Modell (oder nonpublic Inheritance). Die Liste sollte also in etwa so aussehen:

    class List
    {
       knoten* head;
    
       void drauflegen( int i )
       {
          knoten p = new knoten();
          p->i = i;
          
          p->next = head;
          head = p;
       }
    
       // usw...
    };
    

    Bitte beachte, dass du die Regel der Drei (Fünf) beachten musst, da beim Kopieren der Liste nicht einfach den Zeiger des Listenkopfes kopieren darfst, sondern die Liste komplett kopieren musst.

    Und dein bisher "richtiger" Code ist, so leid es mir tut, fürchterlich. Er lädt geradezu ein, Objekte falsch zu gebrauchen und entweder Speicherlecks oder undefiniertes Verhalten durch doppeltes delete zu erzeugen.

    Wir haben Klassen und Objekte erst angefangen. Daher versteh ich auch noch nicht viel davon.
    Ja eben dieses Kopieren ist ja mein Problem.
    Also du meinst ich könnte die Attribute der Klasse auch einfach public machen oder wie meinst du das jetzt?

    DocShoe schrieb:

    Cabooze schrieb:

    Von Iteratoren oder friend funktionen hab ich allerdings noch nie was gehört^^

    Macht nix, gibt ja google.

    Der Punkt ist dass wir nur Dinge benutzen dürfen die wir behandelt haben. Sonst krieg ich die Ohren lang gemacht.



  • Nein, ich meine, dass du eigentlich zwei Klassen brauchst. Eine, die dem Benutzer gibst, damit er eine Menge von Objekten verwalten kann ( List ). Eine zweite, die die Klasse List intern benutzt, um die Elemente zu verwalten.

    Edit:
    Der Google-Hinweis war mit einem Augenzwinkern, ich habe ja schon geschrieben, dass Iteratoren nix für einen Uni Programmierkurs sind.



  • Okay ist halt die Frage ob wir das dürfen. In der Aufgabenstellung steht nur wir sollen dieses kopieren durch eine Funktion realisieren. Und da ist irgendwie wieder der Knackpunkt. Selbst wenn ich eine 2te Klasse erstelle. Ich kann einfach über eine Funktion nicht auf die Attribute zugreifen.

    Zu deiner List funktion.
    Du sagtest ja, mein Code sieht fürchterlich aus^^
    Aber außer dass der Zähler fehlt sehe ich jetzt keinen Unterschied zwischen deiner List und meinem Knoten.



  • Im Prinzip hast du recht, meine List Klasse macht (im Moment) nicht wesentlich mehr als deine knoten Klasse. Aber gehen wir mal weiter, du forderst in deinem Programm mit new Speicher an, wo wird der denn wieder freigegeben? Da brauchst du eine Entscheidung, ob der Knoten auf dem Stack liegt (in deinem Quelltext main, Zeile 3) oder auf dem Heap (Klassen knoten, Zeile 23). Das kann deine Knoten Klasse allein schon nicht mehr handhaben, weil da ein Entscheidungskriterium gebraucht wird. Für diesen Fall brauchst du zwei unterschiedliche Verhalten, das kann ein Flag in der Klasse knoten sein (meh!), oder eine neue Klasse List . List benutzt knoten nur intern und stellt sicher, dass jeder Knoten, der mit new erzeugt wurde auch mit delete wieder freigegeben wird.



  • Ok aber mein Hauptproblem ist jetzt immernoch nicht weg...



  • Cabooze schrieb:

    Ok aber mein Hauptproblem ist jetzt immernoch nicht weg...

    Dein Hauptproblem ist, dass Du an Deiner knoten Klasse festhältst, obwohl die völlig unsinnig ist.
    Klar ist das nicht weg, solange Du nicht daran arbeitest!?


Anmelden zum Antworten