Ich habe den Vorschlag von Herrn Stroustup nicht verstanden, die Kopierstandard- und Verschiebeoperationen für die abstrakte Klasse Shape zu löschen

8

Ich versuche zu verstehen, was der Autor in 3.3.4 Suppressing Operations in seinem neuen Buch (TCPL 4. Ausgabe) vorschlägt, ohne Erfolg.

Auszug aus dem Buch

  

Verwenden der Standardkopie oder -verschiebung für eine Klasse in einer Hierarchie ist   In der Regel eine Katastrophe: Nur einen Zeiger auf eine Basis gegeben, tun wir einfach nicht   wissen, welche Mitglieder die abgeleitete Klasse hat (§3.3.3), so können wir nicht wissen, wie   um sie zu kopieren. Also, das Beste, was zu tun ist, ist normalerweise zu löschen   Standard Kopier- und Verschiebeoperationen; das heißt, standardmäßig zu beseitigen   Definitionen dieser beiden Operationen:

%Vor%
  

Nun wird ein Versuch, eine Form zu kopieren, vom Compiler abgefangen. Wenn du   müssen Sie ein Objekt in einer Klassenhierarchie kopieren, schreiben Sie eine Art von Klon   Funktion (§22.2.4).

Der folgende Code kompiliert beispielsweise nicht mit Shape(const Shape&) = delete; , da die Funktion clone() den Kopierkonstruktor Shape aufruft.

%Vor%     
Wake up Brazil 28.07.2013, 21:04
quelle

2 Antworten

5

Wenn Sie nur einen Zeiger auf ein Shape haben, dann können Sie möglicherweise keine Kopie der tatsächlichen Implementierung erstellen - es wird (wahrscheinlich) größer sein, so dass Ihre Kopie "geschnitten" wird. In Ihrem Beispiel hat Circle eine zusätzliche int a ; das ist nicht Teil der Klasse Shape - die wäre verloren, wenn du einfach ein Shape klasse Objekt kopierst, ohne zu wissen, dass es ein Circle ist (und der ganze Punkt des Polymorphismus ist, dass du nicht "wissen" sollst) "welches Objekt ist welcher Typ, wenn es in generischen Funktionen damit zu tun hat"

Um Probleme zu vermeiden, die durch versehentliches Verwenden von etwas wie:

verursacht werden %Vor%

ist es besser, die Operatoren zu "löschen", die Ihnen erlauben, das zu tun

Da jedoch der Kopierkonstruktor für den von Ihnen beschriebenen Fall benötigt wird, besteht eine Lösung darin, protected zu machen - das schützt vor etwas anderem als einer abgeleiteten Klasse, die es verwendet, und funktioniert korrekt.

Dank robson unten (und auch nachts) ist die Lösung klar, einen Copy-Konstruktor in Circle zu machen. Nur weil Sie keinen für Shape haben, heißt das nicht, dass Sie keinen in der abgeleiteten Klasse haben können:

%Vor%

Der Grund, warum versucht wird, den Shape -Kopierkonstruktor zu verwenden, liegt darin, dass Sie in Ihrer eigenen Klasse keinen haben. Du solltest!

Sie könnten auch tun (wie Robson erklärte):

%Vor%

Und brauche keinen Kopierkonstruktor. Beide Lösungen lösen die "Sie versuchen, eine gelöschte Shape(const Shape &) constructor zu verwenden. Es ist wirklich offensichtlich, sobald Sie es sehen.

    
Mats Petersson 28.07.2013 21:21
quelle
1

Er meinte, dass es schlecht sei, sie von außen zugänglich zu machen, wegen potentieller Objekt-Slicing-Probleme. Wenn Sie die Klasse nicht klonbar machen wollen, reicht das Löschen nicht aus. Andernfalls können Sie sie nur so schützen, dass sie nur innerhalb von clone() und den nachfolgenden Zugriffen verfügbar ist.

    
yuri kilochek 28.07.2013 21:19
quelle

Tags und Links