Diskussion:Kopierkonstruktor

aus Wikipedia, der freien Enzyklopädie
Letzter Kommentar: vor 9 Jahren von Asfdlol in Abschnitt Programmbeispiele
Zur Navigation springen Zur Suche springen

Der Artikel ist zu glatt, deshalb fürchte ich ein kleines bisschen es könnte sich um eine URV handeln. Wenn das nicht der fall ist kategorisieren. --tox 04:01, 23. Jan 2006 (CET)

Ich kenne nur den Begriff „Kopierkonstruktor“ und hätte daher ein anderes Lemma gewählt. Andere Meinungen dazu? --jpp ?! 09:35, 24. Jan 2006 (CET)

Übersetzungsfehler :-(( --141.24.45.85 13:24, 24. Jan 2006 (CET)

Überarbeiten[Quelltext bearbeiten]

Der Artikel ist wie für ein Lehrbuch geschrieben und verfehlt daher den enzyklopädischen Charakter. Außerdem ist er stellenweise unverständlich und insgesamt schlecht strukturiert. Ich bitte die Hauptautoren, den Artikel zu überarbeiten. --Knorxx 11:53, 29. Jan 2006 (CET)

Hat sich nach 2 Jahren nichts dran geändert, hab mal den Baustein eingefügt... das einzige was ich hierran verstehe ist, das es sich um einen speziellen Konstruktor handelt, der wiederum ist eine Form der Methode (in der OOP), auf jeden Fall sollte man in der Einleitung "in der Informatik" rauslassen... es kann ja mal jemand eine Doktorarbeit über die "Gebiete der Informatik" schreiben... viel zu weit gefasst. Sonst ist alles in C++ gefasst, Beispiel wird sofort hingeworfen, und nicht erklärt. Irgendwo wird auch mal Java erwähnt, aber Zusammenhänge werden nicht klar. Gibt viel zu tun hier, Grüße --WissensDürster 15:22, 26. Jun. 2009 (CEST)Beantworten

Programmbeispiele[Quelltext bearbeiten]

Nur weil das Augenmerk auf einem anderen Aspekt liegt (hier auf dem Kopierkonstruktor), ist das meiner Meinung nach keine Freikarte, den Code abseits dem schlecht zu schreiben. Ich spiele damit hauptsächlich auf das Verletzen der Dreierregel an. Zudem erscheint es mir schleierhaft, wieso teilweise die Initialisierungsliste (korrekterweise) verwendet wird (drittes Listing), ansonsten jedoch nicht. Dass die sogenannte "Zuweisungssyntax" nur genau dann verfügbar ist, wenn der Konstruktor nicht explicit ist, wird nicht erwähnt. Es zieht sich Inkonsistenz quer durch den Artikel. Fängt an bei unterschiedlicher Reihenfolge von Member / Methoden, geht über unterschiedliche Positionierung der Zeiger-* bis hin zu unterschiedlicher Einrückung. --Asfdlol (Diskussion) 12:03, 15. Aug. 2014 (CEST)Beantworten

Das Verletzen der Dreierregel bezog sich nicht auf das zweite Listing (da wurde sie gar nicht verletzt, denn keiner der drei betroffenen Methoden war benutzerdefiniert). Es sollte darüber nachgedacht werden, wie sinnvoll die letzte Änderung war, zumindest bzgl. dem Zuweisungsoperator. Die Einführung des Destruktors ins Listing finde ich gut, das hat vorhin gefehlt (ansonsten tritt die Problematik gar nicht auf sondern bleibt bei einem Speicherleck). Über den Kopierkonstruktor lässt sich streiten, denn es würde in dem Fall ein identischer vom Compiler generiert werden. Auf der anderen Seite ist dies hier der Artikel über Kopierkonstruktoren. Der Zuweisungsoperator kann hier auch getrost bei der (public) Version belassen werden, die vom Compiler generiert wird, denn diese erzeugt auch eine flache Kopie. Ausserdem ist hier rhs viel üblicher als z. --Asfdlol (Diskussion) 17:27, 15. Aug. 2014 (CEST)Beantworten
Ich sehe das so: der Destruktor muss definiert werden, weil sonst das ganze Beispiel hinfällig ist. Laut Dreierregel müssen dann auch Kopierkonstruktor und Zuweisungsoperator implementiert werden. Bei letzterem habe auf die Implementierung verzichtet, weil er für das Beispiel irrelevant ist. Mit der Deklaration ohne Implementierung habe ich aber verhindert, dass der Compiler ihn implizit erzeugt; meines Erachtens habe ich damit die Dreierregel eingehalten.
Mit dem “rhs“ hast Du freilich Recht, das sollte umbenannt werden.--EdwardBaynes (Diskussion) 21:38, 16. Aug. 2014 (CEST)Beantworten
"Laut Dreierregel müssen dann auch Kopierkonstruktor und Zuweisungsoperator implementiert werden." Das ist falsch. Von einem muss ist bei der Dreierregel nirgends die Sprache. Es gibt Klassen, bei denen die Dreierregel nicht zum Zuge kommt (die paradigmatischste ist wohl der Referenzenzähler). Ja, du sagst es - für das Beispiel irrelevant. Daher liegt es nahe, seine Deklaration wegzulassen (dasselbe gilt für den Kopierkonstruktor, denn der implizit erzeugte ist einhundertprozentig äquivalent zu deinem eigenen). --Asfdlol (Diskussion) 23:43, 16. Aug. 2014 (CEST)Beantworten
“muss“/“soll“, das ist doch Wortklauberei. Wenn es wirklich ein Muss wäre, würde der Compiler es erzwingen, das ist mir genauso klar wie Dir. Die Regel soll Programmierer davor bewahren, Fehler durch Unterlassung zu machen. Wer es besser weiß, kann sich natürlich auch entscheiden, sie nicht einzuhalten. Aber Leute, die genau wissen, wann sie die Regel nicht einhalten müssen, sind wohl kaum die, die es nötig haben, das Code-Beispiel im Artikel zu lesen.
Dass ich den Kopier-Konstruktor explizit implementiert habe, hat m.E. auch den Vorteil, dass es für den Leser des Beispiels offensichtlich ist, was er tut. Überlässt man dem Compiler die Definition, muss man eben mit Kommentaren erklären, was der Compiler tut. --EdwardBaynes (Diskussion) 14:45, 17. Aug. 2014 (CEST)Beantworten
"Dass die sogenannte "Zuweisungssyntax" nur genau dann verfügbar ist, wenn der Konstruktor nicht explicit ist, wird nicht erwähnt." Ich nehme mal an, dass Du hier "Kopierkonstruktor" meintest und nicht "Konstruktor". Letzterer hat nichts mit der Zuweisungssyntax zu tun, und ob er explicit ist oder nicht spielt keine Rolle (vergleiche auch http://coliru.stacked-crooked.com/a/0edac581dd3e216b). Dass wiederum die Eigenheiten eines explicit Kopierkonstruktors nicht extra behandelt werden, halte ich für absolut richtig, weil das eine Besonderheit ist, die Anfänger nicht brauchen und nicht kennen müssen.
Ganz grundlegend sollten wir uns vielleicht einig werden, was das Ziel der Code-Beispiele ist. Meines Erachtens sollen sie es interessierten Einsteigern und Fortgeschrittenen möglich machen, die Eigenheiten von Kopierkonstruktoren (speziell im Kontext von C++) zu verstehen. Klar kann man als Autor versuchen, in jedem Code-Beispiel den großen Wurf zu landen und alles reinzupacken, was man über C++ weiß. Aber gerade C++ ist eine so umfang- und facettenreiche Programmiersprache, dass das mit Sicherheit jeden Einsteiger überlasten würde. Hier ist meines Erachtens weniger mehr. Die Beispiele sollten daher zwei Eigenschaften haben: Korrektheit und Verständlichkeit. Vollständigkeit hingegen würde ich von einem Wikipedia-Artikel nicht erwarten, sondern höchstens von einem Lehrbuch oder dem C++-Standard. --EdwardBaynes (Diskussion) 19:45, 24. Aug. 2014 (CEST)Beantworten
Bedauerlicherweise bist du im Unrecht. Zunächst mal ist der Kopierkonstruktor auch ein Konstruktor. Des Weiteren sind auch diese nichtkopier-Konstruktoren auch mit der Zuweisungssyntax aufrufbar (in C++03 jedoch nur wenn sie nicht mehr als einen Parameter haben, in C++11 kann jeder nicht-explizite Konstruktor mit der Zuweisungssyntax aufgerufen werden, siehe aggregate initialization). Was ich aus dem Codebeispiel in deinem Link entnehmen soll ist mir ausserdem schleierhaft, denn da wird der Konstruktor, der einen C-String als Parameter hat, nur mit der expliziten Syntax aufgerufen, nicht jedoch mit der impliziten Zuweisungssyntax (was ja aus von mir genannten Gründen gar nicht erst möglich ist, er ist schliesslich explicit). Ein besseres Beispiel, das meine Argumentation zudem untermauert wäre dieses: http://ideone.com/aToTvz
Das Problem ist, dass die Unterschiede zwischen expliziten und impliziten Konstruktoren zwar angewendet werden (im Code), nicht jedoch erklärt.
Ja, da hast du prinzipiell recht. Wenn du noch Konsistenz zur Liste hinzufügst, dann kann ich mich damit einverstanden geben, denn meiner Meinung nach ist Konsistenz vor allem bei Hochsprachen ein Fundamentalsatz. --Asfdlol (Diskussion) 22:20, 24. Aug. 2014 (CEST)Beantworten
Wir reden hier wohl ein Bisschen aneinander vorbei. Deine Kritik am Code-Beispiel im Artikel war ja, dass die Zuweisungssyntax nur in dem Fall verfügbar sei, dass der Konstruktor nicht explicit ist. Der Code in meinem Link ist exakt der Beispiel-Code aus dem Artikel, mit dem Unterschied, dass der Konstruktor explicit ist. Die Zuweisungssyntax in der Zeile MitCopyKonstruktor mitCC2 = mitCC; akzeptiert der Compiler ohne Weiteres. Hier wird eben der Kopierkonstruktor aufgerufen, nicht der Konstruktor (sicher ist ein Kopierkonstruktor auch ein Konstruktor, aber wenn Du den meinst, würde ich Dich bitten, ihn der Verständlichkeit halber auch beim Namen zu nennen). Du hast völlig Recht mit dem, was Du zu impliziten (nicht-Kopier-)Konstruktoraufrufen schreibst, aber so einer kommt in dem Code-Beispiel nicht vor, daher gibt es daran nichts zu bemängeln.
Der implizite Kopierkonstruktoraufruf ist eben doch ein Spezialfall; ich kann zwar nur aus eigener Erfahrung (mit C++03) schreiben, aber ich weiß, dass es in der Praxis eine gute Idee ist, Ein-Parameter-Konstruktoren per Faustregel immer explicit zu machen und nur davon abzuweichen, wenn man genau weiß, was man tut. Einen Kopierkonstruktor explicit zu machen ist mir persönlich in der Praxis noch nicht untergekommen. Speziell für Funktionen, in die nutzerdefinierte Objekte als Werteparameter übergeben werden, aber auch für das Einlagern nutzerdefinierter Objekte in Container, sind implizite Kopierkonstruktoraufrufe unverzichtbar. Der langen Rede kurzer Sinn: Leser auf die Fallstricke von explicit Konstruktoren ("Konstruktor" im Allgemeinen) hinzuweisen, halte ich für sehr sinnvoll. Aber das Code-Beispiel im Artikel würde m.E. nicht davon profitieren, die Besonderheiten von explicit Kopierkonstruktoren zu erklären, die in der Praxis eher eine untergeordnete Rolle spielen.
Was an dem Code-Beispiel nicht ganz stimmig ist, ist vielleicht eher der Text, der dem zweiten Block voran geht: "Es erfolgt in der Deklaration des Objektes die Zuweisung des anderen Objektes oder das Objekt wird als Wertparameter an eine Funktion oder Methode übergeben." Den Satz musste ich dreimal lesen, um ihn zu verstehen. An seiner Stelle würde eine Erläuterung von impliziten und expliziten Aufrufen des Kopierkonstruktors bestimmt viel helfen, um das Beispiel verständlicher zu machen. Aber da müsste ich auch erstmal drüber nachdenken, wie der neue Text korrekt, verständlich und konsistent formuliert werden kann. Im Übrigen hat Konstruktor da leider auch noch eine Lücke. Wenn die Artikel zueinander konsistent sein sollen, muss da auch noch was zu "explizit vs. implizit" beschrieben werden. --EdwardBaynes (Diskussion) 00:08, 25. Aug. 2014 (CEST)Beantworten
Meine Kritik war ursprünglich, dass der Unterschied nicht erläutert wird. Es ist jedoch ebenfalls fragwürdig ob der Konstruktor im Abschnitt "Verwendung", der einen C-String als Argument akzeptiert, explicit sein soll (m.M.n. nicht, siehe std::string).
[...]aber so einer kommt in dem Code-Beispiel nicht vor[...] Doch, jener kommt auch vor (Abschnitt "Beispiel", MitCopyKonstruktor(const char* value)). Später wird ein ähnlicher Konstruktor in einer anderen Klasse als explicit deklariert, was m.M.n. (wie aus genannter Kritik zu entnehmen ist) dazu führt, dass es den Unterschied zu erklären gilt. Ich würde beide als implizit definieren, std::string Foo = "Bar"; gilt es nicht zu vermeiden.
(Persönliche Anmerkung, OT: auch Mehrparameter-Konstruktoren würde ich als explicit deklarieren wenn der Code mit C++11 noch immer guten Stil aufweisen sollte, auch wenn man selbst nicht mit C++11 entwickelt. Ein Anderer tut es vielleicht.)
Einen Kopierkonstruktor explicit zu machen ist mir persönlich in der Praxis noch nicht untergekommen. Mir auch nicht, dürfte auch ziemlich sinnfrei sein denn damit disqualifiziert sich die Klasse vom Gebrauch als Rückgabetyp / Parameter.
Es erfolgt in der Deklaration des Objektes die Zuweisung des anderen Objektes oder das Objekt wird als Wertparameter an eine Funktion oder Methode übergeben. Hoppla, der Satz ist mir entgangen. Dieser ist nicht nur - wie du schon sagtest - schwer verständlich sondern zudem auch noch inhaltlich falsch. Bei der Deklaration einer Instanz wird gar keine Aussage über dessen Initialisierung getroffen, sondern bei der Definition. Und wird dies bei der Definition getan, so geschieht dies wie gesagt mit einer Initialisierung (Konstruktoraufruf), nicht mit einer Zuweisung.
Der englischsprachige Artikel führt die Terminologie der expliziten und der impliziten Konstruktoren gleich zu Beginn ein. Dies ist m.M.n. ein geeignetes Konzept für den Aufbau der Artikel. Wir sollten dies vielleicht im Artikel Konstruktor so einbetten und hier auf diesen neuen Abschnitt verweisen. --Asfdlol (Diskussion) 08:59, 25. Aug. 2014 (CEST)Beantworten