Warum benötigt die Signatur des Operators delete zwei Parameter?

8

Ich habe über das Überladen neuer und Löschen (und verwandte Themen wie Platzierung neu / Löschen) gelesen. Eine Sache, die mich bisher verwirrte, ist, dass die Standardsignatur des Operators delete (im Klassenbereich) lautet:

%Vor%

Löschen heißt so:

%Vor%

Also, wie liefert delete ptr; den zweiten Parameter für die Größe? Kann ich auch annehmen, dass die MyClass * in diesem Fall implizit in das void * konvertiert wird?

    
John Humphreys - w00te 19.10.2011, 15:57
quelle

3 Antworten

9

Kurze Antwort:

Die Operatoren

new und delete werden im Klassenbereich überladen, um die Zuweisung für Objekte einer bestimmten Klasse zu optimieren. Es kann jedoch spezielle Szenarien geben, die auf bestimmte Bestien wie Inheritance zurückzuführen sind. Dies kann zu Zuordnungsanforderungen für mehr als die Klassengröße selbst führen. Der eigentliche Zweck von new und delete overload ist eine spezielle Optimierung für Objekte der Größe sizeof(Base) , nichts größer oder kleiner, diese überladenen Operatoren sollten alle anderen wrong sized Speicheranforderungen an ::operator new und ::operator delete weiterleiten, um dies zu können, muss der Größenparameter als Parameter übergeben werden.

Lange Antwort:

Betrachten Sie ein spezielles Szenario:

%Vor%

Im obigen Beispiel wegen der Vererbung Die abgeleitete Klasse Derived erbt den neuen Operator der Klasse Base . Dies macht den Aufruf eines Operators in einer Basisklasse neu, um Speicher für ein Objekt einer abgeleiteten Klasse zu reservieren. Der beste Weg für unseren neuen Betreiber, diese Situation zu bewältigen, besteht darin, solche Anrufe, die die "falsche" Speichermenge anfordern, wie folgt an den neuen Standard-Operator umzuleiten:

%Vor%

Beim Überladen des delete -Operators muss man auch sicherstellen, dass seit dem klassenspezifischen Operator new die Anforderungen der "falschen" Größe an ::operator new weiterleitet, man "falsch dimensionierte" Löschanforderungen an :: operator delete weiterleiten muss, Da die ursprünglichen Operatoren garantiert sind, diese Anforderungen in einer standardkonformen Weise zu behandeln.

Der benutzerdefinierte Operator delete wird also etwa so aussehen:

%Vor%

Weiterführende Literatur:
Der folgende C ++ - FAQ-Eintrag spricht davon, dass Sie neue und löschende Daten auf eine standardkonforme Art und Weise überladen und für Sie vielleicht eine gute Lesbarkeit haben:

Wie sollte ich iso c ++ standardkonforme benutzerdefinierte neue und löschende Operatoren schreiben?

    
Alok Save 19.10.2011, 16:09
quelle
6
  

Also, wie löscht ptr; Stellen Sie den zweiten Parameter für die Größe?

Wenn der Zeigertyp ein Klassentyp mit einem virtuellen Destruktor ist, aus dynamischen Informationen über den Objekttyp. Wenn es keinen virtuellen Destruktor hat und der pointere-Typ mit dem Zeigertyp übereinstimmt - aus der Kompilierzeit Informationen über die Schriftgröße. Sonst ist delete ptr undefiniertes Verhalten.

    
Tadeusz Kopec 19.10.2011 16:07
quelle
0

Es ist die Aufgabe des Compilers, sich an die Größe zu erinnern, die beim Aufruf von delete freigegeben werden soll. Für delete ptr; wird sizeof(MyClass) übergeben, für delete[] ptr; muss die Anzahl der MyClass im Array gespeichert werden und die korrekte Größe übergeben werden. Ich habe absolut keine Ahnung, wie diese seltsame Ecke der Sprache entstanden ist. Ich kann mir keinen anderen Teil der Sprache vorstellen, in dem sich der Compiler einen Laufzeitwert für Sie merken muss.

    
Mooing Duck 19.10.2011 16:06
quelle

Tags und Links