Open Source im professionellen Einsatz
Linux-Magazin 08/2014

Modernes C++ in der Praxis – Folge 17

Automatik mit Methode

Der C++-Compiler erzeugt einige Methoden automatisch. In C++11 kann der Programmierer das gezielt steuern, indem er eine Reihe deklarativer Schlüsselwörter verwendet.

556

Methoden anzufordern, zu unterdrücken oder zu überschreiben bereitet im klassischen C++ immer wieder Probleme. Der Programmierer muss dabei viele spezielle Regeln im Kopf behalten und anwenden, um keine böse Überraschung zu erleben. Das gehört nun der Vergangenheit an, denn mit modernem C++ lässt sich das Verhalten von Ableitungshierarchien rein deklarativ steuern.

Methoden anfordern und unterdrücken

Der Compiler erzeugt auf Bedarf einige Methoden selbst. Der Kasten "Automatisch" stellt die prominentesten vor. Die Vorteile dieser bei Notwendigkeit erzeugten Methoden liegen auf der Hand. Sie nehmen einerseits dem Profi die lästige Arbeit ab, immer wieder den gleichen Boilerplate-Code zu schreiben, und schützen andererseits den Anfänger davor, Fehler zu machen.

Automatisch

Bei Bedarf erzeugt der C++-Compiler folgende Methoden:

  • Default-Konstruktor
  • Copy/Move-Konstruktor
  • Copy/Move-Zuweisungsoperator
  • Operatoren »new« und »delete« in der einfachen Form
  • Operatoren »new« und »delete« für C-Arrays
  • Destruktor

Doch nicht immer generiert der C++-Compiler die richtige Methode oder entspricht die erzeugte Methode den Anforderungen des Programmierers. Jetzt schlägt die Stunde der neuen Schlüsselwörter »default« und »delete« . Während eine als »default« deklarierte Methode diese vom Compiler anfordert, unterdrückt »delete« eine Methodenerzeugung, die per Default zur Laufzeit verfügbar wäre. Listing 1 zeigt die rein deklarative Anwendung von »default« und »delete« .

Listing 1

default und delete

01 #include <utility>
02
03 class OnlyMove{
04   public:
05
06   OnlyMove()= default;
07
08   OnlyMove& operator= (const OnlyMove&)= delete;
09   OnlyMove (const OnlyMove&)= delete;
10
11   OnlyMove& operator= (OnlyMove&&)= default;
12   OnlyMove (OnlyMove&&) = default;
13 };
14
15 class OnlyOnStack {
16   public:
17     void* operator new(std::size_t)= delete;
18 };
19
20 class OnlyOnHeap{
21   public:
22     ~OnlyOnHeap()= delete;
23 };
24
25 void onlyDouble(double){}
26 template <typename T>
27 void onlyDouble(T)=delete;
28
29 int main(){
30
31   OnlyMove onlyMove;
32   OnlyMove onlyMove1(std::move(onlyMove));
33   // OnlyMove onlyMove2(onlyMove1);
34
35   OnlyOnStack onlyOnStack;
36   // OnlyOnStack* onlyOnStack1= new OnlyOnStack;
37
38   OnlyOnHeap* onlyOnHeap= new OnlyOnHeap;
39   // OnlyOnHeap onlyOnHeap1;
40
41   onlyDouble(3.14);
42   // onlyDouble(2011);
43
44 }

Das Listing stellt ein paar bekannte C++-Idiome vor, die sich mit C++11 sehr elegant lösen lassen, denn der Programmierer drückt darin einfach seine Intention aus. Der Compiler sorgt anschließend für die Implementierung. So sind Objekte der Klasse »OnlyMove« in den Zeilen 3 bis 13 ausschließlich verschiebbar, denn der Code unterbindet das Generieren des Copy-Konstruktors und -Zuweisungsoperators (Zeilen 8 und 9). Dagegen fordert er das Generieren des Move-Konstruktors und -Zuweisungsoperators (Zeilen 11 und 12) explizit an.

Auf Heap und Stack

Unterbindet der Programmierer wie in Zeile 17 die Generierung des »operator new« , so lässt sich das Objekt nicht auf dem Heap erzeugen, sondern nur noch auf dem Stack. Genau das Gegenteil bewirkt das Unterdrücken das Destruktors in Zeile 22. Objekte vom Typ »OnlyOnHeap« müssen alloziert werden.

Der Einsatz der neuen Schlüsselwörter beschränkt sich aber nicht auf Klassenhierarchien. Die freie Funktion »void onlyDouble(double)« (Zeile 25) stellt einen sehr interessanten Anwendungsfall in Kombination mit dem Funktionstemplate »template <typename T> void onlyDouble(T)= delete« (Zeilen 26 und 27) dar. Diese Kombination bewirkt, dass der Compiler für Argumente vom Typ »double« die Funktion, für alle anderen Argumente das Funktionstemplate verwendet. Die C++-Regel ist es, dass der Compiler im Zweifelsfall die freie Funktion vorzieht, falls die Argumente für diese gleich gut oder besser passen als für das Funktionstemplate.

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 4 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • C++

    Beim deklarativen Programmieren drückt der C++-Programmierer unter anderem mit Hilfe von Schlüsselwörtern aus, was er erreichen möchte. Der Compiler kümmert sich dann um den weiteren Weg.

  • C++

    Mit der Move-Semantik und konstanten Ausdrücken besitzt modernes C++ eine kräftige Stellschraube, um die Performance einer C++-Anwendung in die richtige Richtung zu drehen.

  • Erfrischend neu

    An der Sprache C++ ändert sich selten etwas. Doch nun steht mit dem C++0x ein neuer Standard vor der Tür, von dem Neulinge wie Könner profitieren sollen. Mit Move-Semantik, Lambda-Funktionen und Aggregatzuweisungen bringt er viele Modernisierungen in die Programmiersprache.

  • Vala im Detail

    Die junge High-Level-Sprache Vala erleichtert die Entwicklung von Anwendungen, die auf der GObject-Bibliothek aufsetzen. Dieser Artikel beleuchtet die Eigenschaften und Eigenarten der Sprache genauer.

comments powered by Disqus

Ausgabe 10/2017

Digitale Ausgabe: Preis € 6,40
(inkl. 19% MwSt.)

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.