Operatoren zum Speichermanagement

Bjarne Stroustrup, der Erfinder der Programmiersprache C++, schreibt in seinem Buch „Design und Entwicklung von C++“, dass er ursprünglich die Konstruktoren new und die Destruktoren delete nennen wollte. Das ist meiner Ansicht nach auch recht logisch, trotzdem hat er es nicht gemacht.
Warum eigentlich nicht?

Des R&aauml;tsels Lösung ist eigentlich recht einfach: new und delete sind Operatoren und noch dazu kann man diese Operatoren überladen.

Was machen die new und delete-Operatoren eigentlich ?

Die Konstruktoren konstruieren auf vorhandenem Speicher eine Klasseninstanz. Der Destruktor baut es wieder ab. Aber der Programmierer muss sich nicht darum bemühen, dass Speicher besorgt und freigegeben wird, denn genau dafür sind die Operatoren new und delete da.

In der Regel besteht kein Grund, die Operatoren zu überladen, möchte man jedoch die Speicherverwaltung optimieren, zum Beispiel weil man sehr viele, sehr kleine Instanzen in einem Memorypool unterbringen möchte, so kann man die operatoren new und delete entsprechend überladen.

Grundsätzlich lässt sich so eine beliebige Speicherverwaltung aufbauen, da es hier allerdings nur um die Überladung des Operators geht, überlade ich die Operatoren hier in der Form, dass sie zusätzlich einen Text auf den Bildschirm schreiben, wenn sie Speicher anfordern oder freigeben:

class Fraction
{
...
inline void * operator new( size_t size );
{
void * address = ::operator new( size );
printf( ">>> Speicher für Fraction angefordert: %d Bytes an %x\n", size, static_cast( address ) );
return address;
}
inline void * operator delete( void * address );
{
printf( "<<< Speicher von Fraction freigegeben: Adresse %x\n", address );
return ::operator delete( size );
}
...
};

Für die Klasse 'Fraction' wird nun mit Hilfe dieser Operatoren Speicher besorgt und wieder freigegeben. Dabei muss zum einen klargestellt werden, dass operator new() und operator delete() nur dann aufgerufen werden, wenn auch wirklich Speicher angefordert oder freigegeben werden soll. Bei Objekten, die auf dem Stack konstruiert werden, wird kein Speicher angefordert. Hier ist die klare Unterscheidung zu Konstruktoren und Destruktoren.

Weiterhin fällt auf, dass die selbstgeschriebenen Operatoren für die Klasse Fraction globale Operatoren rufen. Es gibt also auch einen globalen operator new() und einen globalen operator delete(). Diese können natürlich auch überladen werden, trotzdem sollte dies nach Möglichkeit vermieden werden. In einem Projekt, an dem mehrere Personen arbeiten, kann das Überladen globaler Funktionalität unerwartete Ergebnisse bei den Kollegen hervorrufen. Beschränken Sie sich also darauf, ihre eigenen Klassen zu spezialisieren oder bieten Sie Ihre Spezialisierung als eigene Klasse an, so dass jede Klasse die Spezialisierung erben kann, wenn sie von Ihrem Verfahren profitiert.

m
“If I only listended to my customers, I would give them a fast horse.”
Henry Ford

Inhalt
Hauptseite
Unär
Binäre
Postfix
Index
Funktoren
Speichermanagement
Konvertierungen

Operatoren
Arith.: +, -, *, /, %
Inc/Dec: ++(), --(), ()++, ()--
Bits: |, &, ^
Shift/IO: >>, <<
Logisch: ||, &&, !, ~
Vergleich: ==, !=, >, >=, <=, <
Zuweisen: =, +=, -=, *=, /=, %=, |=, &=, ^=, <<=, >>=
Index: []
Zugriff: *, ->, ->*
Functor: ()
Speicher: new, new [], operator new, operator new [], delete, delete []
Datentyp: Konvertierung