Beherrschen Sie C++ ?

Robert Hoschek

Selbst Software-Entwickler mit langjähriger Erfahrung müssen zugeben, daß sie manchmal auf Aufgabenstellungen stoßen, die sich als harte Nuß erweisen. So mancher C++ Guru greift dann zum Buch oder stellt seine Frage in eine einschlägige Newsgroup im Internet.

Beherrschen Sie C++ ? Dann überlegen Sie sich einmal folgende Aufgabe:

Sie möchten eine Klasse MyClass definieren und einem anderen Programmierer zur Verfügung stellen, allerdings mit der Einschränkung, daß sie nur am Heap erzeugt werden darf. Dadurch wird der Stack des Programms nicht belastet, was für die gestellte Aufgabe wichtig ist. Der Programmierer soll Ihre Klasse also folgenderweise verwenden:

MyClass *pmclass = new MyClass(); // Instanz am Heap anlegen

delete pmclass; // Instanz vom Heap entfernen

Dagegen soll folgende Verwendung nicht erlaubt sein:

MyClass mclass; // Instanz der Klasse am lokalen Stack erzeugen

Natürlich können Sie nicht verhindern, daß jemand diese Zeile eingibt. Sie müssen den Compiler dazu bringen, daß er die Zeile als falsch zurückweist, weil er sie nicht kompilieren kann. Wie Sie sicher wissen, haben Objekte, die am lokalen Stack erzeugt werden, ein angenehmes - zumindest klar definiertes - Verhalten: Sie werden beim Verlassen des Gültigkeitsbereichs, also spätestens am Programmende, gelöscht. Das Löschen eines Objekts ist aber immer mit dem Aufruf des Destruktors verbunden. Was nun aber, wenn der Compiler den Destruktor nicht aufrufen kann? Sehen Sie sich die Definition der Klasse (bzw. das für uns interessante Fragment) an:

class MyClass {

public:

    MyClass();

private:

   ~MyClass();

};

Während der Konstruktor public, d.h. von außen zugänglich ist, ist der Destruktor private deklariert. Er kann von außen, in unserem Fall vom Compiler, nicht aufgerufen werden. Da der Compiler also die Instanz der Klasse beim Verlassen des Gültigkeitsbereichs nicht richtig behandeln kann, verweigert er die Kompilierung. Warum - können Sie jetzt fragen - kann man dann das Objekt am Heap erzeugen und löschen? Dazu muß man nur überlegen, was delete eigentlich bedeutet. delete ist ein Operator, also eine Memberfunktion unsere Klasse. Und diese hat Zugriff auf private Memberfunktionen.

Jetzt nehmen wir einmal den umgekehrten Fall an; Sie wollen den Heap verbieten und den Anwender Ihrer Klasse zwingen, den lokalen Stack zu verwenden. Damit vermeiden Sie z.B. Probleme mit Speicherbereichen, die nicht mehr freigegeben werden. Kann man das (mit Unterstützung des Compilers) erzwingen?

Man kann. Unsere Klasse sieht jetzt folgendermaßen aus:

class MyClass {

private:

static void * operator new (size_t size);

static void operator delete (void *ptr);

};

Wir haben den new und delete Operator als private deklariert. Sie können also von außen nicht mehr aufgerufen werden. Folglich muß der Versuch

MyClass *pmclass = new MyClass(); // Instanz am Heap anlegen

scheitern.

War das ein Thema, das Sie interessiert? Dann empfehle ich Ihnen die Lektüre von Scott Meyers „Mehr Effektiv C++ programmieren“, in diesem Buch finden Sie alles, was Ihre Programmierung effektiver macht.