Sie sind hier: Buchauszüge Einführung  
 BUCHAUSZÜGE
Vorwort
Inhaltsverzeichnis
Einführung
Typwandlungen

EINFÜHRUNG
 
Einführung

Nach insgesamt 8 Jahren intensiver Bemühung ist die Sprache C++ nun endlich standardisiert. Das entsprechende Dokument (kurz „der Standard“ genannt) ist immerhin 748 Seiten stark und beschreibt die Syntax und Semantik der Sprache so präzise, dass nahezu kein Spiel­raum mehr für Streitfragen existiert.

Allerdings ist der Standard auch für einen erfahrenen Programmierer über weite Strecken schlichtweg unlesbar. Zu kompliziert sind die Formulierungen, zu schwierig die Details, zu ausgefallen manche Bei­spiele. Dies ist der Preis, der für eine genaue Definition der Syntax und Semantik der Sprache zu bezahlen ist. Während der „normale“ Sprachgebrauch noch relativ einfach zu beschreiben ist, muss das Standarddokument mehr leisten: Zu jedem denkbaren Programm muss anhand des Standards entschieden werden können, ob es syn­taktisch zulässig ist, oder nicht. Ist es syntaktisch korrekt, muss der Standard auch eindeutige Aussagen über das Verhalten (die sog. Se­mantik) des Programms definieren[1]. Für eine so mächtige Sprache wie C++ keine einfache Aufgabe.

Das Standarddokument ist daher für die Praxis der Programmierung denkbar ungeeignet. Was nützt es, wenn eine Konstruktion vielleicht zwar syntaktisch korrekt ist, von den gängigen Compilern jedoch (noch) nicht unterstützt wird?[2] Für die Praxis benötigt man andere Refe­renzen, die unter anderem auch den heutigen Stand der Compi­lertechnik berücksichtigen.

&&  Inhalt

Dieses Buch beschreibt die Aspekte, die für die erfolgreiche Ent­wicklung von Programmen mit Hilfe von C++ wichtig sind, und zwar so­wohl für das Design als auch für die Implementierung. Besonderes Augen­merk wird dabei auf die Objektorientierung gelegt, für die C++ ganz ausgezeichnete Sprachmittel bereitstellt.

C++ ist jedoch keine rein objektorientierte Sprache, sondern lässt ganz explizit auch andere Programmierstile zu. Neben der objektori­entierten Programmierung streifen wir die prozedurale Programmie­rung, wie sie in traditionellen Sprachen wie z.B. C üblich ist, und werfen einen Blick auf die funktionale Programmierung, die durch das mächtige Sprachmittel der Schablonen (Templates) in C++ mög­lich geworden ist.

Das insgesamt verfügbare Material über die Softwareentwicklung mit C++ ist für ein einziges Buch zu umfangreich. Es war daher sinnvoll, eine Zweiteilung vorzunehmen:

q In dem hier vorliegenden Buch mit dem Titel Die Kunst der Pro­grammierung mit C++ konzentrieren wir uns auf die Syntax und Semantik der Spra­che. Hier werden die Sprachmittel vorgestellt, die C++ für den Programmierer bereithält. Dabei wechseln sich theoretische Kapitel mit prakti­schen Fallstudien ab: In den theore­tischen Kapiteln wer­den jeweils neue Sprachkonstruktionen vor­ge­stellt, die dann im nachfolgenden Praxiskapitel sofort an konkreten Pro­blem­stel­lun­gen angewendet werden. Parallel dazu gibt es ein Projekt (d.h. eine vollständig ausgearbeitete Aufgabe), das in den einzelnen Kapiteln ständig weiter entwickelt wird und am Ende des Buches in einer professionellen Lösung vorliegt. Zu jedem Thema gibt es darüber hinaus Übungen. Die Musterlösungen des Autors finden sich auf der Internet-Seite des Buches.

q In einem weiteren Buch mit dem Titel Die fortgeschrittene Kunst der Pro­grammierung mit C++ betrachten wir Themen, die vor al­lem beim Einsatz von C++ bei der professionellen Programmierung in großen Projekten zum Tragen kommen. Einsatz der C++-Stan­dard­bib­liothek, Entwurfsmuster, Beherrschung von Komplex­ität, Kontrakt­orientiertes Programmieren, Zusammenarbeit mit anderen Pro­grammiersprachen, Techniken zum Fehlermanagement und nicht zuletzt Stil und Formfragen bei der Programmie­rung sind nur einige Themen, die dort behandelt werden. Die Beherrschung der Sprache an sich wird dabei vor­ausgesetzt.

Das vorliegende Buch besteht aus zwei Teilen:

q Teil I: Die Grundlagen. Im ersten Teil werden die Sprachmittel der Sprache C++ vorgestellt, die wohl in jeder der bekannten Pro­grammiersprachen irgendwie vorhanden sind: Zahlen, Zeichen, Zeichenketten, Arithmetik, Deklarationen und Definitionen, Aggre­gationen, Verweise, Funktionen. Da diese C++ - Sprachmittel na­hezu identisch von der Sprache C übernommen wurden, bietet dieser Teil dem erfahrenen Programmierer wahrscheinlich viel Be­kanntes. Der Teil I zeigt, dass C++ nicht nur eine objektorientierte Programmiersprache ist, sondern auch eine Sprache, in der man klassisch funktional und bei Bedarf auch maschinennah (hier im Gegensatz zu plattformunabhängig gesehen) programmieren kann.

q Teil II: Das Richtige C++. Dies ist der Hauptteil des Buches. Hier werden zuallererst einmal die Sprachmittel beschrieben, die zur Definition und Implementierung von objektorientierten Abstraktio­nen bereitstehen. Dazu gehören vor allem Klassen, Objekte, Ver­erbung sowie Sprachmittel zur Realisierung des Polymorphismus, der in allen objektorientierten Sprachen eine zentrale Rolle ein­nimmt.

q C++ ist eine der wenigen Sprachen, die einen Mechanismus wie Schablonen (templates) unterstützt. Dadurch können Abläufe un­abhängig vom Typ der betroffenen Werte formuliert werden. Eine der Hauptanwendungen für Schablonen sind sicherlich Container, die mit ihrer Hilfe typsicher formuliert werden können. Darüber hinaus ermöglichen Schablonen Techniken, die bis dahin undenk­bar waren, und die auch heute noch Gegenstand heißer Diskussi­onen sogar unter Fachleuten sind. Schablonen sind im Standard erst relativ spät exakt definiert worden, die heutigen Compiler ha­ben auch hier noch die meisten Defizite.

q Zu den fortgeschritteneren Sprachmitteln gehört auch das Thema Fehlerbehandlung mit Ausnahmen (exceptions). Dinge wie Über­laden von Operatoren, Referenztypen sowie einige andere, weni­ger spektakuläre Sprachmittel, die das Abstraktionskonzept abrun­den, werden ebenfalls hier behandelt.

&&  Schwerpunkt

Der Schwerpunkt dieses Buches liegt auf der angemessenen Vorge­hens­weise bei der Softwareentwicklung. Die zentrale Frage lautet:

Wie setze ich eine gegebene Problemstellung in ein C++ Programm um?

Dabei ist hier nicht nur die Funktionalität alleine gemeint, wie es lei­der von so vielen Entwicklern in der Praxis verstanden wird: selbst­verständlich muss das Programm korrekt arbeiten, es muss genau das Problem lösen, für das es geschrieben wurde.

Korrektheit ist jedoch nur eine Eigenschaft eines Programms. Unter kommerziellen Gesichtspunkten ebenfalls wichtig sind aber auch Ei­genschaften wie z.B. Erweiterbarkeit, Wartbarkeit, Fehlertoleranz, Ro­bustheit, Verständlichkeit oder auch Kosteneffizienz bei der Erstel­lung, um nur einige wichtige zu nennen. Gerade diese Eigenschaften werden neben der eigentlichen Funktionalität von Software immer wichtiger. Sie sind es, die gute von normaler oder sogar schlechter Software unterscheiden.

Zu einer gegebenen Problemstellung sind viele Lösungen möglich, die unterschiedliche Ausprägungen der gerade genannten Merkmale besitzen. Die Frage, die die Spreu von Weizen trennt, ist letztendlich

Wie erreiche ich zu einer gegebenen Problemstellung ein qualitativ hochwertiges Programm?

Zur Beantwortung dieser Frage muss man einerseits die zur Verfü­gung ste­henden Sprachmittel der Sprache C++ genau kennen, zum andern aber auch die Vorgehensweisen beherrschen, die bei der Um­setzung ei­nes Problems in ein „gutes“ Programm Anwendung finden. Vor allem der zweite Punkt wird oft vergessen. Gerade C++ Einsteiger ver­wenden die komplexen und mächtigen Sprachmittel der Sprache viel zu ausgiebig und darüber hinaus (im Sinne professioneller Pro­grammierung) oftmals falsch. Die unüberlegte Verwen­dung von mächtigen C++ Konstruktionen führt dann schnell zu un­wartbaren oder sogar fehlerhaften Programmen. Es ist genau dieser Punkt, der bei vielen (auch erfahrenen) Umsteigern, die sich mit C++ versucht haben, im End­effekt zu Ablehnung führt. Die Komplexität der Pro­gramme, die mit C++ möglich sind, ist auch einer der Gründe, warum die Sprache Java von einigen Entwicklern als „das bessere C++“ be­zeichnet wird.

C++ und C

Die Wurzeln der Sprache C++ liegen in der Programmiersprache C. C++ ist syntaktisch und semantisch (bis auf wenige Ausnahmen) eine Obermenge von C. Das bedeutet z.B., dass ein „ordentliches“ C Pro­gramm auch mit einem C++ Compiler übersetzt werden kann. Von daher sind die in C vorhandenen Sprachmittel auch in C++ nahezu vollständig vorhanden. Das bedeutet jedoch auch, dass C++ einige der Unschönheiten und Probleme der Sprache C besitzt. Hätte man sie Sprache ohne Rücksicht auf C neu entworfen, wären sicherlich ei­nige Dinge anders gelöst.

Die Kompatibilität zu C war eines der wesentlichen Entwurfskriterien der Sprache C++, konnte doch dadurch sichergestellt werden, dass die neue Sprache sofort in der industriellen Softwareentwicklung An­wendung finden und das dort gebräuchliche C nach und nach ver­drängen konnte. Die in C bewanderten Programmierer konnten sofort die C++ - Vorteile verwenden, ohne eine komplett neue Sprache ler­nen zu müssen. Nach und nach konnten dann die leistungsfähigeren neuen Sprachmittel dazugenommen werden – ein Bruch mit erzwun­genem Neuanfang wie bei der Umstellung auf eine komplett andere Programmiersprache konnte somit vermieden werden. Auch heute ist C++ noch kompatibel mit C, d.h. in korrektem C geschriebene Pro­grammteile können (mit einigen kleinen Ausnahmen) problemlos in einem C++ Programm verwendet werden. Dadurch können Investiti­onen in C-Bibliotheken (z.B. Datenbankanbindung, Numerik) auch nach einem Umstieg auf C++ weiter verwendet werden. Diese Eigen­schaften der Sprache C++ haben sicherlich wesentlich dazu beigetra­gen, dass C++ eine so weitgehende Verbreitung in der industriellen Datenverarbeitung gefunden hat.

C++ bietet zusätzlich neue und wesentlich andere Sprachmittel als C. Deshalb sind mit C++ andere Programmiertechniken möglich. Dinge wie Kapselung, Ableitungen oder Polymorphismus sind in C nicht vorhanden, sondern können höchstens mühsam simuliert werden. Eine Bibliothek mit Containern und vorgefertigten Algorithmen gehört nicht zu C, sondern muss bei Bedarf hinzugekauft oder selbst entwi­ckelt werden.

In diesen Zusammenhang wird folgende Frage häufig gestellt: Soll man C lernen, bevor man sich mit C++ befasst?  Die Antwort ist ein klares NEIN! C++ ist zwar syntaktisch eine Obermenge von C, damit sind die Gemeinsamkeiten jedoch schon erschöpft. C++ ermöglicht ganz andere und bessere Programmiertechniken als C, wie wir in die­sem Buch sehen werden.

&&  C++ und Java

Es wird oft behauptet, dass Java das bessere C++ sei. Java ist „voll­ständig objektorientiert“[3], einfacher als C++ und trotzdem genauso mächtig – und vor allem: plattformunabhängig[4]. Java besitzt automati­sche Speicherbereinigung (garbage collection), Introspection und die Programme können in Browsern laufen. Darüber hinaus gibt es mehr Bibliotheken als für C++. Die Verfechter der Sprache begründen mit diesen Argumenten, dass Java grundsätzlich besser als C++ sei.

Was sie jedoch nicht erwähnen ist, dass Java im Vergleich mit C++ wesentliche Schwächen im Sprachdesign und in der Laufzeitbiblio­thek hat. Die Einfachheit der Sprache wird mit eingeschränkten Aus­drucksmöglichkeiten erkauft.

Man kann deshalb nicht sagen, dass Java oder C++ generell die bes­sere Sprache sei, sondern nur, dass für eine gegebene Aufgabenstel­lung wahrscheinlich Java oder C++ die besseren Implementierungs­möglichkeiten bieten wird. Benötigt man unbedingt die Ablauffähig­keit in einem Browser, führt derzeit wohl oft kein Weg an Java (oder in Zukunft verstärkt an der .NET-Architektur) vorbei[5]. Doch bereits beim Thema garbage collection kann Java höchstens noch als plus verbuchen, dass diese Technik dort bereits standardmäßig vorhanden ist, während ein collector für C++ zusätzlich hinzugenommen werden muss[6]. Das Fehlen einer automatischen Speicherverwaltung in C++ wird von vielen sogar als Vorteil gesehen: Sie kostet Ressourcen, die man z.B. in einem zeitkritischen System nicht investieren will. Durch den Einsatz bestimmter Sprachmittel, die Java nicht, sehr wohl aber C++ besitzt, kann außerdem die Notwendigkeit einer automatischen Speicherbereinigung sogar vollständig wegfallen. Ein Java-Anwender hat hier keine Wahl, ein C++ Anwender schon.

Das Thema „C++ vs. Java“ wird auf jedem Seminar, in den Pausen je­der Schulungsveranstaltung und natürlich auch im Internet kontrovers diskutiert. Meist handelt es sich um persönliche Meinungen, teilweise werden auch Erfahrungen bei einem konkreten Projekt veröffentlicht, selten jedoch findet man eine Analyse, warum dieses oder jenes Sprachmittel prinzipiell gut oder schlecht ist. Dieser Unterschied zwi­schen gemachter Erfahrung in einem konkreten Projekt und prinzi­pieller Eignung einer Sprache zur industriellen Softwareentwicklung ist wichtig, wird aber allzu oft nicht beachtet.

Wir gehen in diesem Buch auf den Sprachenstreit nicht weiter ein. An Stellen, an denen sich die Java-Philosophie von der C++-Philosophie unterscheidet, betrachten wir allerdings beide Seiten. Damit hat der Leser die Möglichkeit, für seine konkrete Aufgabenstellung die geeig­nete Sprache zu wählen[7].

&&  C++ und C#

Der neue Stern am Sprachenhimmel ist sicherlich C#. Der Name „C-Sharp“ soll dabei ausdrücken, dass die Sprache einen „Halbton“ über C liegt. C# ist vom Design her eine Java-ähnliche Sprache, mit auto­matischer Speicherbereinigung etc. C# ist jedoch auf die Microsoft-Welt zugeschnitten und ist Teil der .NET Entwicklungsplattform. Die Sprache enthält spezielle Konstruktionen zur Bedienung von Micro­soft-Schnittstellen (wie z.B. delegates). C# vermeidet einige der schlimmsten Nachteile von Java (z.B. fehlende Destruktoren[8]) und kann sich so zu einer interessanten Alternative zu Java entwickeln.

Wahrscheinlicher jedoch wird die Zukunft von C++, Java und C# mehr durch politische als durch sachliche oder technische Argumente bestimmt. Ein wichtiges Argument ist in diesem Zusammenhang, dass .NET offengelegt ist und es somit anderen Firmen als Microsoft mög­lich ist, eigene Implementierungen auf den Markt zu bringen. So wird .NET derzeit für UNIX implementiert, eine Open-Source Implementie­rung ist angedacht. Demgegenüber ist Java eine proprietäre Sprache, für die es nur einen Anbieter gibt (Fa. SUN), der keine weiteren An­bieter neben sich zulässt. Allerdings sind die wesentlichen Spezifika­tionen der Sprache sowie der Java Virtual Machine auch hier öffent­lich zugänglich. Die Sprache ist nicht standardisiert, sondern sozusa­gen „Eigentum“ von SUN. An eine Standardisierung (d.h. an die Übergabe der Sprache an ein Standardisierungsgremium (wie z.B. ANSI oder ISO) ist nicht gedacht. Es ist zu erwarten, dass diese prop­rietäre Politik von der Industrie nicht auf Dauer akzeptiert werden wird.

&&  Sprache und Bibliothek

Wie jede moderne Sprache besitzt auch C++ eine Bibliothek zur Lauf­zeitunterstützung. Syntax und Semantik dieser C++ Standardbiblio­thek sind im C++-Standard genauestens festgelegt. Dabei ist wichtig, dass zwar das Verhalten einer Funktion, Klasse etc. (Semantik) defi­niert ist, nicht jedoch die Implementierung. Compilerhersteller sind daher frei, ihre Implementierung beliebig zu wählen, solange die vom Standard gesetzten Anforderungen erfüllt werden. Diese sind jedoch oft so detailliert, dass in der Praxis nur Implementierungen mit margi­nalen Unterschieden zu finden sind.

&&  Compilerversionen

In diesem Buch behandeln wir hauptsächlich Standard-C++, d.h. die Sprache in der Form, wie sie im Standard definiert ist. Standard-C++ ist unabhängig von einem bestimmten Compiler oder Hersteller. An­dererseits benötigt man einen konkreten Compiler, um mit C++ ar­beiten zu können. Insofern ist für die Praxis nicht unbedingt das reine C++ des Sprachstandards von Interesse, sondern eher der Implemen­tierungsumfang des gegebenen Compilers.

Kein heute bekannter Compiler implementiert den Standard vollstän­dig und zu 100 Prozent korrekt. Dies bedeutet, dass es theoretisch möglich ist, ein korrektes Programm zu schreiben, dass von keinem heutigen Compiler übersetzt werden kann. Dazu muss man allerdings exotische Sprachmittel in ungewöhnlichen Kombinationen verwen­den. Nahezu alle bekannten Differenzen liegen im Bereich der Schablonen, die zugegebenermaßen das von der Theorie her wohl schwierigste Sprachmittel überhaupt darstellen. Nicht umsonst ver­zichten ver­gleichbare andere Sprachen (Java[9]) vollständig darauf.

Für die Praxis ist die Standardkonformität der gängigen Compiler gut genug, um professionell damit arbeiten zu können. Außerdem brin­gen die Compilerhersteller regelmäßig neue Versionen ihrer Pro­dukte auf den Markt. Gerade im Bereich der Standardkonformität der Com­piler wird sich in den nächsten zwei bis fünf Jahren noch einiges än­dern. Wir erwarten, dass die wichtigsten Compiler den Standard im­mer besser unterstützen werden. Alle anderen werden mit Marke­ting­problemen zu kämpfen haben und letztendlich vom Markt ver­schwinden. Evtl. auftretende Probleme der Standardkonformität sind daher hoffentlich temporärer Natur.

Wir beschreiben in diesem Buch deshalb Standard-C++ und nicht den Implementierungsumfang eines bestimmten Produktes. Die in diesem Buch vorgestellten Codebeispiele sind mit allen gängigen Compilern übersetzbar. An den (wenigen) wichtigen Stellen, an de­nen es Probleme gibt, weisen wir explizit darauf hin.

&&  Sprachversionen

Die Sprache C++ ist ursprünglich nicht in ihrer heutigen, standardi­sierten Form definiert worden. Es gab vielmehr einige Vorversionen, die sich grob in die folgenden Entwicklungsstände aufteilen lassen:

q C mit Klassen. Dies war die allererste Sprachversion, die von Bjarne Stroustrup vor 1980 entwickelt wurde. Ziel war es, einige der Probleme der Programmiersprache C zu überwinden, aber trotzdem deren Vorteile wie z.B. Effizienz und Portabilität beizu­behalten. „C mit Klassen“ wurde damals in mehreren größeren Forschungsprojekten bei AT&T[10] äußerst erfolgreich eingesetzt. Die Sprache war damals nicht formal beschrieben, sondern wurde in Diskussionen zwischen Mitarbeitern und Programmierern stän­dig verändert.

q ARM-Stand. Ca. 1983 trat „C mit Klassen“ erstmals aus dem For­schungsbereich in die Öffentlichkeit. Durch den großen Erfolg war den Beteiligten klar, dass nun eine Formalisierung notwendig war. Margaret Ellis und Bjarne Stroustrup schrieben daraufhin (Mai 1990) als erstes formales Dokument The Annotated C++ Reference Manual (ARM), in dem die Sprache auf dem damaligen Stand mehr oder weniger formal beschrieben wurde. Der Name „C++“ löste „C mit Klassen“ ab, dabei sollte das „C“ für die Aufwärtskom­patibilität zur Sprache C stehen, das „++“ dagegen für die Verbes­serungen, die gegenüber C nun zur Verfügung standen. Das ARM sollte auch zur Vorbereitung der Standardisierung der Sprache durch das American National Standardisation Institute (ANSI) und später die International Standardisation Organisation (ISO) die­nen.

     Das Annotated Reference Manual war lange Zeit die Bibel aller C++-Programmierer, auch heute noch verbindet mancher Soft­wareentwickler mit dem Wort „C++“ diese Version. Sie beschreibt einen Sprachstand, der heute als ARM-Stand bezeichnet wird. In diesem Stand sind – neben dem obligatorischen Klassenkonzept – bereits Ableitungen und virtuelle Funktionen, Überladen von Ope­ratoren, Referenzen, und eine rudimentäre typisierte E/A-Biblio­thek vorhanden. Im ARM werden bereits Schablonen (templates) und ein neues Konzept zur Behandlung von Fehlersituationen (über sog. Ausnahmen (exceptions)) vorgestellt, der Status dieser Sprachmittel war jedoch „experimentell“. Man wollte damit Erfah­rung gewinnen, wie sich diese Innovationen in der Praxis be­währten – und in der Tat hat sich die formale Definition dieser Sprachmittel (vor allem der Schablonen) bis zum heutigen Stan­dard noch einige Male verändert. Die in der Praxis erarbeiteten Erfahrungen waren für die endgültige Definition dieser Sprachmit­tel eine große Hilfe.

q Vor-Standardisierungs-Stand (pre-standard). Im Dezember 1989 wurde das X3J16-Komittee der ANSI formal mit der Standar­disierung der Sprache beauftragt, 1991 kam die Arbeitsgruppe 21 der ISO (ISO WG21) hinzu. Als Basis für die Standardisierung diente das ARM sowie der Standard der Programmiersprache C (ISO/IEC 9899), neben weiteren Dokumenten wie z.B. Konventio­nen über die Terminologie oder den für Quellcodes zu verwen­dende Zeichensatz.

     Im Zuge der Arbeit des Standardisierungskomitees wurde die Spra­che nach und nach verändert und erweitert. Die im ARM noch als „experimentell“ gekennzeichneten Sprachmittel wurden prinzipiell akzeptiert und weiter entwickelt, weitere wesentliche Teile (wie z.B. Namensbereiche (name spaces)) kamen hinzu. Parallel zur Standardisierung der Sprache an sich wurde die Definition einer Laufzeitbibliothek in Angriff genommen.

q Standard. Am 1. September 1998 präsentierte das Komitee das Er­gebnis der Standardisierungsbemühungen: Der International Stan­dard ISO/IEC 14882 liegt nun in der ersten Ausgabe (First Edition 1998-09-01) vor. Damit sind Syntax und Semantik der Program­miersprache C++ sowie der zugehörigen C++ Standardbibliothek international festgeschrieben.

&&  Pre-Standard und Standard

Für die Softwareentwicklung heute sind diese beiden „Versionen“ der Sprache relevant. Neue Programme sollten selbstverständlich in Stan­dard-C++ erstellt werden, soweit der verwendete Compiler dies zu­lässt – die Unterschiede sind (wie gesagt) in der Praxis verschmerz­bar.

Eine sehr große Anzahl bestehender C++-Programme ist jedoch nicht nach den Vorgaben im Standard erstellt worden, da der Standard bei ihrer Erstellung noch gar nicht existierte. Glücklicherweise können diese Programme in der Regel auch mit einem standardkonformen Compiler übersetzt werden, wenn man einige Besonderheiten be­achtet. Eventuell sind einige kleinere Korrekturen notwendig, die je­doch auf Grund von Syntaxfehlermeldungen bei der Übersetzung sofort erkannt werden können.

Auf Grund der zahlreichen bestehenden C++-Altsysteme ist der Pre-Standard für die Praxis also nicht ganz unwichtig. Wir gehen deshalb wo erforderlich gesondert darauf ein. 

&&  Voraussetzungen

Dieses Buch ist kein Einführungsbuch in die Programmierung. Wir gehen davon aus, dass der Leser bereits Erfahrung in der Program­mierung von An­wendungen hat, die über triviale Beispiele hinausge­hen.

Wir behandeln weiterhin keine Fragen der Installation oder der Be­dienung von Compilern, Entwicklungsumgebungen, Debuggern etc. Wir gehen davon aus, dass der Leser einen funktionsfähigen Compiler besitzt und auch bedienen kann. Auf der Internetseite des Buches gibt es Hinweise zu gängigen Entwicklungssystemen, darunter auch zu nichtkommerziellen Produkten wie dem GNU-Compiler. Weiterhin gibt es auf der Internetseite Standard-Projektdateien bzw. Makefiles für die gängigen Systeme.

&&  Support über das Internet

Das Buch wird über eine Internetrepräsentanz unterstützt. Die Ein­stiegsseite ist

 

http://www.PrimaProgramm.de

 

Der Quellcode sämtlicher größerer Beispiele ist über diese Seite er­reichbar. Die Quellen sind nach Kapiteln geordnet, für die vollständi­gen Fallbeispiele und die einzelnen Versionen des durchgängigen Projekts gibt es zusätzlich fer­tige Projektdateien für die wichtigsten Compiler, sowie eine generelle Make-Datei.

Darüber hinaus enthält die Seite ständig Informationen über neuere Entwicklungen aus dem Bereich C++ sowie eine Reihe interessanter Links zu anderen Ressourcen über C++, Objektorientierung und ver­wandte Themen. Es lohnt sich also, öfters mal vorbeizuschauen. Eine weitere Quelle von In­formationen bietet der Server des Vieweg-Ver­lages, der unter der Adresse

 

http://www.Vieweg.de

 

erreichbar ist.

Wer wirklich keinen Internetzugang hat, kann die Quelltexte auch auf Diskette zu einem Kostenbeitrag von EUR 10.- erhalten. Bitte wenden Sie sich dazu an den Verlag, oder direkt an den Autor.

Anregungen, Wünsche und Verbesserungen sind willkommen an fol­gende Email-Adresse:

 

Martin.Aupperle@PrimaProgramm.de

 

&&  Literatur

Die folgende Liste enthält eine Aufzählung der aus Sicht des Autors wichtigsten Bücher und Veröf­fentlichungen:

q C++ Standard

     Der C++ Standard ist das Referenzdokument für die Sprache C++. Er kann vom ANSI oder der ISO gegen einen Kostenbeitrag von US$18 in elektronischer Form bezogen werden (Adresse siehe In­ternetseite des Buches) .

     Die Sprache wird, wie es sich für einen Standard gehört, präzise und vollständig be­schrieben. Teilweise werden kleine Beispiele gegeben. Das Papier ist äu­ßerst zäh zu lesen und es bedarf ausrei­chender Erfahrung mit C++, um überhaupt sinnvoll damit arbeiten zu können. Auf jeden Fall nichts für C++-Neulinge oder für die Softwareentwicklung in der Praxis, aber die definitive Entschei­dungsinstanz, wenn es um Streitfragen der Syntax oder Se­mantik geht.

q  The Draft C++ Standard

     Dieses Papier beschreibt den Stand der Sprache, wie er zur Nor­mung durch ANSI/ISO angenommen wurde. Der Draft (wie das Papier vereinfacht genannt wird) enthält nur marginale Unter­schiede zum Standard, ist aber dafür im Internet (Adresse siehe Internetseite des Buches) frei erhältlich.

q  Bjarne Stroustrup: The C++ Programming Language, 3rd ed. Addison-Wesley. Reading, Massachusetts, 1997

     Das Buch gibt eine vollständige Übersicht über die Sprache C++. Es be­handelt den vollständigen Sprachstandard nach ANSI/ISO ohne Berücksichtigung von Defiziten heutiger Compiler etc. Zu den Sprachkonstruktionen werden kurze Beispiele gegeben, die die Kon­strukte erläutern. Jedes Kapitel schließt mit Aufgaben und Übungen für den Leser, allerdings werden keine Antworten gege­ben. Das Buch enthält am Ende auch ein Kapitel über Designfra­gen und ihre Auswirkungen auf die Gestaltung von Programmier­sprachen allgemein und C++ im Besonderen. In Fachkreisen wird das Buch auch einfach als The Book oder The Bible bezeichnet.

q  Bjarne Stroustrup: The Design and Evolution of C++. Addi­son-Wesley. Reading, Massachusetts, 1994

     Das Buch ist sehr interessant für Leute, die sich für Historie und Hinter­grund der Sprache C++ interessieren. Der Autor gibt Be­gründungen, warum bestimmte Spracheigenschaften so und nicht anders implementiert wurden. Insbesondere das Verhältnis zur Sprache C und die daraus resultierenden Konsequenzen werden ausführlich behandelt. Mögliche Alternativen oder mögliche zu­sätzliche Sprachelemente werden ebenfalls angesprochen und auch die Gründe, warum sie letzt­endlich verworfen wurden.

q  Nicolai M Josuttis: The C++ Standard Library. Addison-Wesley. Reading, Massachusetts, 1999

     Dieses Buch befasst sich ausschließlich mit der C++ Standardbiblio­thek. Die Bibliothek wird vollständig und ausführ­lich behandelt. Zu allen Bereichen gibt es Beispiele.

q  Marshall Cline and Greg Lomow: C++ FAQs. Addison-Wesley. Reading, Massachusetts, 1995

     FAQ bedeutet Frequently Asked Question (etwa: häufig gestellte Frage). Das Buch behandelt solche häufig gestellten Fragen zu C++. Die Antworten sind kurz und präzise und werden teilweise durch Erläuterungen oder Kommentare ergänzt. Im Internet ist eine zweite, kleinere Version der FAQs vorhanden, die re­gelmäßig in den Newsgroups gepostet wird und auch über die Internetseite des Buches erreichbar ist. Marshal Cline pflegt auch die elektroni­sche Version. Die elektronische Version ist aktueller, das Buch ist dage­gen wesentlich ausführlicher.

q  Martin Aupperle: Die Fortgeschrittene Kunst der Program­mierung mit C++. Vieweg-Verlag, 2003

     In diesem Buch geht es um Fragen der industriellen Softwareent­wicklung mit C++. Der erste Teil befaßt sich mit der C++-Stan­dardbibliothek, und zwar sowohl mit dem Einsatz der bestehenden Funktionalität als auch mit ihrer Erweiterung durch eigene Kon­struktionen. Im zweiten Teil werden Programmiertechniken vorge­stellt, die sich in großen Projekten bewährt haben. Zu den Themen des zweiten Teils gehören Entwurfsmuster, Techniken zur Beherr­schung von Komplex­ität, Kontrakt­orientiertes Programmieren, Zu­sammenarbeit mit anderen Pro­grammiersprachen, Techniken zum Fehlermanage­ment sowie Fragen der Softwarequalität.  Zum Buch gibt es eine Internetseite, von der auch ein Stilhandbuch (stylegu­ide) heruntergeladen werden kann.

q  C++ Report

     Eine monatlich erscheinende Fachzeitschrift ausschließlich zum Thema C++. Bekannte Autoren schrieben sowohl für Profis, Fort­geschrittene und auch für C++-Einsteiger. Die Zeitschrift ist aller­dings seit Sommer 2000 eingestellt. Es lohnt sich auf jeden Fall, in einer Bibliothek einmal die letzten Jahrgänge durchzublättern.

q  C/C++ Users Journal

     Eine monatlich erscheinende Fachzeitschrift, die sich mit Themen rund um die Programmiersprachen C und  C++ befasst. Die Zeit­schrift enthält regelmäßig Beiträge bekannter Autoren zum Thema C++. Nach der Einstellung des C++ Report schreiben die meisten Autoren nun für „CUJ“, wie das C/C++ Users Journal vereinfacht genannt wird.

Darüber hinaus gibt es eine Reihe interessanter Quellen im Internet. Die Internetseite des Buches enthält einige Links.

&&  Einige Anmerkungen

Zum Schluss dieses einführenden Kapitels betrachten wir noch einige Behauptungen über C++, die man in Programmiererkreisen oft hören kann, die aber so pauschal nicht richtig sind.

&   C++ ist nichts anderes als C mit einigen Verbesserungen

Diese Aussage ist richtig und zugleich falsch – je nach Blickwinkel.

Richtig ist, dass C++ syntaktisch (mit unwesentlichen Ausnahmen) eine Obermenge der Sprache C ist. Das bedeutet z.B., dass ein „or­dentliches“ C Programm auch mit einem C++ Compiler übersetzt werden kann. Durch die neuen Sprachmittel werden die bekannten Probleme der Programmierung mit C verringert oder ganz vermieden.

Dies ist jedoch nur die halbe Wahrheit. Richtig ist nämlich auch, dass C++ eine völlig andere Programmiersprache als C ist, wenn man die Programmiertechniken betrachtet. C++ bietet ganz andere Möglich­keiten, Programme wartungsfreundlicher, besser wiederverwendbar und nicht zuletzt schneller und damit kosteneffizienter zu erstellen als dies mit den traditionellen Programmierstilen möglich war. Aus dieser Sicht ist die obige Aussage völlig falsch.

Java/C/Basic/Smalltalk/Perl/Delphi/Lisp ist besser als C++!

Die Liste der „besseren“ Programmiersprachen könnte noch beliebig erweitert werden. Aber was bedeutet „besser“? Sicherlich gibt es Problemstellungen, für die C++ nicht die geeignete Sprache ist. Möchte man z.B. Programme erstellen, die innerhalb der grafischen Umgebung eines Web-Browsers ablaufen sollen, ist vielleicht Java oder sogar eine Scriptsprache besser geeignet.

Alle diese Sprachen haben ihren Anwendungsbereich. Betrachtet man jedoch die große Gruppe der allgemeinen Problemstellungen (die also nicht auf spezielle Randbedingungen Rücksicht nehmen müs­sen), ist C++ in den allermeisten Fällen die bessere Wahl.

In der Praxis kommen jedoch auch nicht-technische Aspekte hinzu. Die Komplexität der Sprache schreckt Programmierer und Manager gleichermaßen ab. Java wird oft deshalb als geeigneter angesehen, weil die Syntax und das „Handling“ einfacher sind. Dies ist korrekt – die Komplexität steckt jedoch in den Anforderungen, die einmal mit einem Programm realisiert werden sollen. Es ist durchaus nicht klar, wieso eine einfachere Sprache besser zum Lösen schwieriger Aufga­ben geeignet sein soll als eine mächtigere Sprache. Folgt man solchen Argumentationen, müsste man eigentlich in Assembler oder Basic am allerbesten programmieren können. Die Erfahrung zeigt, dass dies je­doch nicht so ist. Vergessen darf man allerdings auch nicht, das mächtige Werkzeuge auch ausreichend Kompetenz im Umgang er­fordern – sonst sind die Ergebnisse verheerend[11].

Aber C++ ist so komplex!

Dieses Argument wird oft von Verfechtern von einfacheren Program­miersprachen wie C oder Java vorgebracht. Es ist auf der einen Seite sogar berechtigt! C++ kann eine extrem komplexe Sprache sein – man kann Sprachkonstrukte so kombinieren, dass wirklich schwierige und teilweise fehlerträchtige Programme entstehen.

Andererseits ist es so, dass normale Aufgabenstellungen in C++ ein­fach, sicher, lesbar und damit wartungsfreundlich implementiert wer­den können. Ein Einsteiger kann mit C++ schnell Ergebnisse, und zwar vor allem deshalb, weil er sich auf die problemorientierten As­pekte konzentrieren kann und sich nicht so sehr um die maschinen­orientierten Dinge kümmern muss. Die mächtigen Abstraktionsmittel der Sprache C++ sowie die hervorragende Unterstützung durch die Standardbibliothek machen dies möglich.

Die meisten der schwierigeren Konstruktionen werden heute nicht von Anwendungsprogrammierern, sondern von Bibliotheksimple­mentierern verwendet. Sie können durch Einsatz dieser Sprachmittel hervorragende Performance, geringen Ressourcenverbrauch sowie andere positive Eigenschaften ihrer Bibliotheken realisieren[12]. Der An­wender sieht meist von dieser Komplexität nichts, da sie in der Implementierung der Bibliotheken verborgen ist.

Dies bedeutet natürlich nicht, dass man zur Implementierung von Bibliotheken die Sprache derart ausreizen muss. Häufig verwendete Bibliotheken wie z.B. die C++ Standardbibliothek können jedoch da­von Gebrauch machen, um das Letzte an Performance herauszuholen.

Ein bekannter Ansatz geht davon aus, dass mächtige Werkzeuge not­wendigerweise auch entsprechend komplex sind. Dies trifft auch für C++ zu, allerdings mit der Ergänzung, dass ein Programmierer mit dieser Komplexität nicht unbedingt konfrontiert werden muss: Er kann sich auch auf die einfacheren Sprachmittel beschränken.

Aber C++ ist langsam!

So oft man dieses Argument auch hört: Es ist schlichtweg falsch. Übersetzt man ein Programm mit einem C- und einem C++-Compiler, werden beide Versionen gleich schnell laufen. C++ erzeugt daher nicht automatisch ineffizienteren Code.

Ein anderer Vergleich ist hier schon aussagekräftiger: Implementiert man eine gegebene (nicht triviale) Problemstellung einmal mit C und dann getrennt mit C++, werden sich beide Implementierungen auf Grund der unterschiedlichen zur Verfügung stehenden Sprachmittel der beiden Sprachen wahrscheinlich stark unterscheiden. Folgende Effekte können häufig beobachtet werden:

q    Der Programmierer hat auch in C++ wie in C programmiert, d.h. die Lösungen unterscheiden sich nur unwesentlich. Die Laufzeiten sind vergleichbar.

q    Der Programmierer verwendet zwar die C++ Sprachmittel, jedoch nicht unbedingt korrekt. Durch die ungeschickte Programmierung läuft die C++ Implementierung deutlich langsamer und ist evtl. auch deutlich größer.

q    Der Programmierer verwendet die C++ Sprachmittel und setzt diese sorgfältig und korrekt ein. Das C++ Programm läuft schnel­ler als die C-Version!

Wie man sieht, hängt alles von der korrekten Verwendung der Spra­che ab. Es ist durchaus möglich, dass C++ Programme sogar effizien­ter als ihre C-Pendants sind, wenn man Design und Implementierung in Richtung Laufzeit optimiert. Dies macht C++ z.B. auch für die Implementierung von Betriebssystemen oder embedded systems ge­eignet.

In größeren Systemen tritt allerdings noch ein weiterer Effekt auf. Implementierungen in C++ neigen dazu, qualitativ hochwertiger als Implementierungen in niedrigeren Sprachen zu sein. Wiederver­wendbarkeit und Wartungsfreundlichkeit sowie ein besserer Umgang mit Fehlersituationen sind in C++ nicht nur leichter zu realisieren als in C, sondern kommen oft nahezu automatisch, wenn man einige Entwicklungsprinzipien beachtet. Dadurch tendieren C++ Programme auch bei gleicher Funktionalität dazu, mehr Ressourcen als C-Pro­gramme zu benötigen.

Aber C++ ist nicht plattformunabhängig!

Dieses Argument wird meist im Vergleich zu Java zitiert. Bei genaue­rer Betrachtung ist aber auch dieses Argument nicht haltbar. C++ - Programme sind sogar noch eher plattformunabhängig als Java-Pro­gramme. Dies liegt natürlich an den unterschiedlichen Sprachversio­nen sowie an den unterschiedlichen Versionen der Java Virtual Ma­chine, die auf den verschiedenen Rechnern vorhanden sein können. In der Praxis bedeutet dies, dass aus Java’s Anspruch Write Once, Run Anywhere bereits Write Once, Test Anywhere geworden ist. Dies be­deutet einen erheblichen Aufwand für die industrielle Softwareent­wicklung. Standard-C++ - Programme verhalten sich dagegen auf je­der Plattform absolut gleich.

Allerdings fehlen C++ standardmäßig Bibliotheken zum Zugriff auf die zu Grunde liegende Plattform oder für grafische Benutzeroberflä­chen, so wie sie bei Java z.B. mit dem Abstract Windowing Toolkit oder mit Swing vorhanden sind. Da heute die meisten Programme eine GUI benötigen, scheint C++ hier zunächst im Nachteil zu sein. Es gibt allerdings externe C++ - Bibliotheken, die eine plattformunab­hängige GUI-Programmierung ermöglichen[13]. Somit ist hier C++ nicht im Nachteil: der Unterschied zu Java ist lediglich, dass die GUI-Bib­liotheken bereits „zum System“ gehören, während sie bei C++ extern hinzugenommen werden müssen. Hier kommt ein weiterer Vorteil zum tragen: während man z.B. in Java in der Praxis die Swing-Bib­liothek verwenden muss[14], kann man bei C++ eine Auswahl aus mehre­ren Anbietern treffen.

 



[1]  Diese Definition kann auch bedeuten, dass das Verhalten undefiniert ist. In sol­chen Fällen macht der Standard keine Aussagen über die Semantik des betref­fenden Programms.

[2]  In der Tat gibt es einige solche Sprachkonstruktionen, die zwar im Standard aus­drücklich erlaubt, jedoch noch von keinem der heutigen Compiler akzeptiert werden.

[3]  So wird es zumindest gerne dargestellt. Natürlich gibt es auch in Java prozedu­rale Elemente, die allerdings dort über den Umweg von Klassen for­muliert wer­den müssen. Nicht für jede Aufgabe ist Objektorientierung geeignet: schon die Wandlung eines String in eine Zahl hat nichts mit OOP zu tun.

[4]  Die Firma SUN bezeichnet Java mittlerweile nicht mehr als plattformunabhängig, sondern als eigene Plattform.

[5]  Allerdings gibt es auch Bestrebungen, C++ zu Bytecode zu compilieren, der dann von jeder JVM (Java Virtual Machine) ausgeführt werden könnte.

[6]  Es gibt sowohl freie als auch kommerzielle Produkte (z.B. der Firma Great Circle), die eine automatische Speicherverwaltung für C++ bieten. Näheres auf der Internetseite zum Buch.

[7]  Auf der Internetseite zum Buch gibt es einige weitere Gedanken sowie einen (zu­gegebenermaßen persönlich gefärbten) Vergleich zwischen C++ und Java.

[8]  Java besitzt finalizer, diese sind jedoch mit den C++-Destruktoren nur bedingt ver­gleichbar.

[9]  Die für Java 1.5 vorgesehenen sog. Generics sind nur entfernt mit C++ Schablo­nen vergleichbar. Auf der Webseite zum Buch findet sich eine Diskussion.

[10]  American Telephone and Telegraph Company, damaliger Arbeitgeben von Bjarne Stroustrup

[11]  In meinen Seminaren über C++ verwende ich ein drastischeres Beispiel: Wenn man zum Mond fliegen will, benötigt man ein leistungsfähiges Werkzeug. Nie­mand erwartet, dass man nach einem Fahrkurs von 20 Stunden in der Fahr­schule ein solches Gerät bedienen kann. Aus der Sicht des Projektleiters des Mondprogramms gibt es auf dem Markt jedoch hauptsächlich Leute mit norma­ler Fahrschulausbildung. Also wird die Mondfähre gestrichen und man versucht, das Unterfangen mit normalen Straßenfahrzeugen durchzuführen – weil man eben das Personal dafür billig bekommt. Gibt es später Probleme, werden noch ein paar Leute mehr eingestellt – Manager zählen eben gerne Köpfe, und Pro­grammierer ist Programmierer – oder sollte es doch Unterschiede geben?

[12]  Wer einmal mit Java’s SWING gearbeitet hat, wird das Argument sofort verste­hen

[13]  Die Internetseite des Buches gibt einen Überblick über die wichtigsten GUI-Bib­liotheken für C++.

[14]  Prinzipiell ließe sich natürlich auch für die Java-Plattform eine alternative GUI-Bib­liothek entwickeln. Da jedoch die SWING-Bibliothek mitgeliefert wird, ist diese heute ein Quasi-Standard. Alternative Bibliotheken hätten es da schwer.