2016-03-28 7 views
0

Das Buch, das ich verwende, möchte ich LIFO-Stacks mit Konstruktoren in C++ implementieren. Die erste Implementierung ist ziemlich einfach, weil sie das Objekt in einer Funktion als Referenz übergeben soll (der folgende Code hat also eine zusätzliche & in pushexternaler Funktion). Allerdings weiß ich nicht, wie man die zweite Version richtig implementiert. Es will, dass ich es mache, indem ich das Objekt nach Wert übergebe. Daher erstellt es eine Kopie des Objekts, und nach dem Verwenden einer Push-Funktion auf einem Stapel ist das gedrückte Element nicht mehr vorhanden. Ich weiß nicht, wie ich es richtig machen soll, wenn ich es nach Wert überlasse. Ich dachte irgendwie über einen Kopierkonstruktor nach, aber ich habe es ausprobiert und es scheint nicht zu funktionieren ...Übergabe von Objekt nach Wert und Änderung in C++

Dies ist der Code, der in dem Buch geschrieben wird. Ich bin eigentlich nicht, es zu ändern, ich kann nur meine eigene Klasse/zusätzliche Funktionen schreiben:

void pushexternal(Stack s, int a) { 
    s.push(a); 
} 

int main() { 
    Stack s; 
    s.push(0); 
    s.push(1); 
    s.push(2); 
    pushexternal(s, 3); 
    pushexternal(s, 4); 
    return 0; 
} 

und das ist ein Teil meiner Implementierung:

#include <iostream> 
using namespace std; 

class Stack { 
public: 
int ind; 
int * arr; 

Stack() 
{ 
    arr = new int[25]; 
    ind = -1; 
} 
~Stack() 
{ 
    delete [] arr; 
} 

void push(int val) 
{ 
    arr[++ind] = val; 
    cout << "Added " << arr[ind] << " to " << ind << endl; 
} 
}; 

mir bewusst bin, dass vorbei Wert wird hier nicht empfohlen, aber ich frage mich wirklich, wie kann ich es richtig funktionieren lassen, wenn Wertübergabe obligatorisch ist. Das einzige, was mir in den Sinn kommt, ist eine Art Kopierkonstruktor zu schreiben ...? Natürlich funktioniert mein Code hier nicht, da es eine Kopie erstellt, die eine Variable schieben soll, aber wenn es Wert überschreitet, ist es gegangen, wenn es die Funktion verlässt ...

Die Ergebnisse dieses Programms sollten wie folgt aussehen:

Added 0 to 0 
    Added 1 to 1 
    Added 2 to 2 
    Added 3 to 3 
    Added 4 to 4 
+0

Sie können das Array, auf das mit 'arr' gezeigt wird, zwischen Instanzen teilen und eine Referenzzählung durchführen. Sie müssen auch 'int' freigeben, vielleicht als letztes Element des Arrays oder als Mitglied einer Implementierungsstruktur, die freigegeben wird. Normalerweise würde man das mit 'std :: shared_ptr' lösen, ohne das Rad neu zu erfinden. Wie auch immer, zeig uns, was du probiert hast. – LogicStuff

+0

Ich würde nicht zu viel Zeit damit verbringen. Sammlungen nach Wert sind ziemlich nutzlos und werden selten benutzt, zumindest sollten sie * selten benutzt werden. – EJP

+0

Wenn Sie "Stack" als Wert an "pushexternal" übergeben möchten (dh den Stapel kopieren) und immer noch das Original betreffen, besteht die einzige Möglichkeit darin, dass der Kopiervorgang eine flache Kopie ist, dh alle Kopien des gleichen "Stacks" teilen sich tatsächlich eine einzelne Instanz der Stack-Daten. Ersetzen Sie zum Beispiel 'int * arr 'durch' std :: shared_ptr > arr'. Dies ist jedoch eine schreckliche Idee in Bezug auf Code-Design. –

Antwort

0

Wenn Sie ein zusätzliches Mitglied in Ihrem arr Mitglied zuzuweisen waren, Sie dann arr[0] statt ind als Index verwenden könnte. Auf diese Weise zeigt der Zeiger arr auch dann, wenn Ihr Stapelobjekt nach Wert kopiert wird, immer noch auf denselben Speicher.

Ähnliche, möglicherweise komplexere Lösungen existieren, die darin bestehen, dass Ihr Objekt einen Zeiger auf eine Struktur mit ind und arr enthält.

+0

'delete [] arr;' wird andere Stacks mit Dangling-Zeigern verlassen –

Verwandte Themen