Chapitre 1 Introduction et généralités Au sommaire de ce chapitre • L’historique du C++ • La programmation procédurale et orientée objet • Les différences entre compilateur et interpréteur • Le cycle de travail • Les librairies orientées objet • Les différences entre le C et le C++ • Le résumé des différents chapitres de cet ouvrage Le Tout en Poche C++ poursuit un double objectif : vous permettre de maîtriser un des langages de programmation les plus utilisés par la communauté des développeurs et vous fournir les connaissances nécessaires à l’utilisation des nombreuses librairies C++ 1 C++ commercialisées. Sachez en effet que le C++ permet de développer des programmes sur de nombreuses plates-formes, parmi lesquelles nous pouvons citer le DOS, Windows, Unix, Linux, etc. Cet ouvrage vous propose une approche pratique du développement d’applications C++. Chaque concept y fait l’objet d’exemples de code qui vous donneront une idée précise des diverses possibilités offertes par le langage. Ce chapitre présente les caractéristiques fondamentales du C++ par rapport aux autres langages de programmation, en particulier par l’étude des différences entre les langages système et les langages évolués d’un côté, et les interpréteurs et les compilateurs de l’autre. Vous y découvrirez également les étapes à respecter pour générer un programme C++. Dans ce contexte, un premier programme vous guidera pas à pas afin de vous fournir les éléments fondamentaux du développement C++. Cet ouvrage s’adresse à tous ceux qui veulent découvrir les possibilités offertes par le C++. En conséquence, ce livre s’adresse à la fois aux débutants et aux programmeurs C qui souhaitent maîtriser les évolutions proposées par le C++. Historique du C++ L’informatique — dans les distributeurs automatiques de billets, les cartes téléphoniques, le Minitel, les micro-ordinateurs — prend de plus en plus de place dans notre vie de tous les jours. Pour qui les utilise, ces différents périphériques sont des interfaces qui leur permettent de retirer de l’argent, de téléphoner, de rechercher une adresse ou de surfer sur l’Internet. Ces magnifiques programmes ne représentent pourtant qu’une suite d’impulsions ou de non-impulsions électriques qui mettent en évidence le rôle de la base 2 (binaire) où tout élément manipulé par l’ordinateur correspond à une suite de 1 et de 0. Les premiers informaticiens codaient leurs programmes de cette manière. La nécessité d’améliorer la communication entre la machine et le développeur devint très vite évidente : les premiers langages de programmation firent leur apparition. L’assembleur proposa ainsi 2 Introduction et généralités d’écrire les programmes avec des commandes mnémoniques du type MOV ECX, EAX. Vinrent ensuite des langages évolués comme le BASIC ou le COBOL qui s’approchaient de plus en plus des langues parlées (de l’anglais en l’occurrence). Un langage système est un langage qui permet d’accéder à toutes les ressources du système (mémoires, registres, ports, etc.) en définissant des programmes très puissants. Ces langages présentent deux inconvénients majeurs. Ils utilisent généralement une syntaxe ésotérique qui ne facilite pas la lecture et la mise à jour des programmes. D’autre part, leur caractère rudimentaire fait qu’un grand nombre d’instructions est nécessaire pour obtenir un résultat probant. Au contraire, un langage évolué utilise une syntaxe très proche de l’anglais, ce qui facilite l’écriture et la mise à jour des programmes. Ces langages disposent également d’un jeu d’instructions permettant de réaliser des traitements très évolués. Cependant, vous devez savoir que plus un langage est évolué, plus il est difficile de l’utiliser dans un autre contexte que celui pour lequel il a été défini. Dans les années 70, un ingénieur du nom de Dennis Ritchie créa un nouveau langage baptisé C dont la particularité était de pouvoir être utilisé à la fois comme un langage système et comme un langage évolué. Ce langage peut en effet être utilisé pour accéder à toutes les ressources de la machine (y compris en insérant du code assembleur dans un programme C), et propose en standard une kyrielle de routines (appelées fonctions) qui permettent de réaliser des opérations évoluées. Sachez en outre que définir de nouvelles fonctions fait partie intégrante du travail des développeurs C qui constituent de cette manière de véritables boîtes à outils représentées par ces fonctions. Depuis son apparition, le C a évolué jusqu’à ce qu’un autre ingénieur, Bjarne Stroustrup, décide d’y apporter des modifications de fond. Cette mise à jour majeure consista à apporter au langage C les avantages de l’approche orientée objet (voir ci-dessous). A sa sortie, à la fin des années 80, ce nouveau langage fut baptisé C with classes, puis C++. 3 C++ Quelle est la signification du nom C++ ? Comme vous le découvrirez dans le Chapitre 3, l’instruction i++ (héritée du C) permet d’incrémenter de la valeur 1 le contenu de la variable i. Le C++ constitue donc une incrémentation, une amélioration du langage C ! Le C++ est un sur-ensemble du C. A ce titre, il dispose à la fois de l’ensemble des outils et caractéristiques du langage C et d’outils spécifiques au C++. Comme vous le découvrirez dans la suite de ce chapitre, ce langage est utilisé dans un grand nombre de librairies dont l’objectif est de créer des applications en mode graphique (par exemple sous Windows). Le C++ existe sur un grand nombre de plates-formes (Windows, Unix, etc.). Cela signifie qu’en respectant certaines contraintes, vous pouvez définir des programmes portables sur ces différents systèmes. La première de ces contraintes consistera à vous assurer que vous n’utilisez pas d’outils dédiés à une seule cible. La seconde contrainte sera de compiler votre programme pour chacun des systèmes cibles. Une instruction est une opération élémentaire qui correspond le plus souvent à une ligne de code dans un programme. La déclaration et l’initialisation d’une variable ou l’appel d’une fonction sont des exemples d’instructions C++. Un fichier source correspond au fichier texte que le développeur écrit pour indiquer les instructions à exécuter. Un programme désigne, selon les circonstances, soit le fichier source contenant les instructions à exécuter, soit le programme exécutable qui sera lancé. Un programme exécutable (ou un exécutable) correspond au fichier exécutable qui sera créé et lancé par le développeur. A l’exécution d’un programme, on dit qu’il se charge en mémoire. Ce fichier porte généralement l’extension ".exe". 4 Introduction et généralités De la programmation procédurale à la programmation orientée objet Les premiers langages de programmation étaient généralement constitués d’une suite d’instructions s’exécutant de façon linéaire. Dans ce contexte, le lancement d’un programme débutait par l’exécution de la première instruction du fichier source et se poursuivait ligne après ligne jusqu’à la dernière instruction du programme. Cette approche linéaire, bien que simple à mettre en œuvre, a très rapidement montré ses limites. En effet, les programmes monolithiques de ce type ne se prêtent guère à l’écriture de grosses applications et ne favorisent absolument pas la réutilisation du code. En conséquence sont apparus d’autres langages (tels que le C) qui proposaient une approche radicalement différente : l’approche procédurale. L’approche procédurale (ou modulaire) consiste à découper un programme en une série de fonctions (ou procédures). Ces fonctions contiennent un certain nombre d’instructions qui ont pour but de réaliser un traitement particulier. Le calcul de la circonférence d’un cercle, l’impression de la fiche de paie d’un salarié sont des exemples de traitements qui peuvent être symbolisés par des fonctions. Dans le cas de l’approche procédurale, un programme correspond à l’assemblage de plusieurs fonctions qui s’appellent entre elles. Une fonction regroupe une ou plusieurs instructions qui permettent de réaliser une tâche précise. Une fonction possède un nom qui permet de l’appeler, c’est-àdire d’exécuter toutes les instructions qu’elle contient. Les fonctions favorisent la modularité des programmes. Grâce à elles, un problème complexe peut être découpé en plusieurs sous-problèmes. Cela signifie qu’un programme se compose de plusieurs fonctions qui s’appellent entre elles. Ce mode de fonctionnement facilite la maintenance d’un programme dans la mesure où l’application n’est pas symbolisée par un bloc monolithique, mais par un ensemble de petites unités de code sur lesquelles il est facile d’agir. 5 C++ Sachez que ces fonctions peuvent constituer les éléments d’une boîte à outils qui pourront être réutilisés pour les nouveaux développements. Le Chapitre 2 traite spécifiquement de la définition et de l’utilisation des fonctions. L’approche modulaire présente également des inconvénients. D’une part, elle a tendance à dissocier les données des fonctions qui les manipulent. D’autre part, elle ne fournit pas de technique permettant de favoriser la spécialisation des fonctions existantes. Dès le début des années 80, une nouvelle technologie a été créée afin d’améliorer ce mode de fonctionnement : la programmation orientée objet (POO). Cette technique est destinée à améliorer la réutilisation des outils existants et à favoriser la spécialisation de ces mêmes outils. Dans ce contexte, une nouvelle entité, appelée objet, a été créée afin de regrouper les fonctions et les données. Comme vous le découvrirez à partir du Chapitre 6, ces objets sont devenus des acteurs incontournables des développements informatiques. Le terme objet est parfois abusivement employé pour désigner ce qu’on appelle en C++ une classe. La classe représente le moule, le gabarit qui permet de créer les objets. En d’autres termes, la classe correspond dans les faits à la déclaration d’un type de donnée qui permet de créer des variables, les objets (appelés également instances de classe). Une classe est également appelée famille d’objets. Par exemple, une classe permettant de gérer des voitures regrouperait les caractéristiques d’une voiture et permettrait de créer plusieurs objets de ce type. Un programme qui utilise l’approche objet s’appuie sur trois techniques fondamentales qui seront présentées en détail, respectivement aux Chapitres 6, 8 et 9 : • l’encapsulation ; • l’héritage ; • le polymorphisme. 6 Introduction et généralités L’encapsulation permet de réunir au sein d’une même entité appelée classe des données (variables) et des traitements (fonctions). Cette technique s’accompagne également d’un système de protection qui permet de contrôler l’accès aux données et traitements de la classe. Cela signifie qu’il est possible de cacher le fonctionnement interne d’une classe et ainsi éviter que les objets de cette classe soient utilisés de façon non conforme. Les variables qui appartiennent à une classe sont appelées des données membres. Les fonctions qui appartiennent aux classes sont appelées des fonctions membres ou des méthodes. L’héritage permet de bénéficier du patrimoine existant, c’est-àdire de réutiliser les classes existantes. Dans ce contexte, il est possible de définir une nouvelle classe à partir d’une autre. Cela signifie que la classe descendante (ou dérivée) pourra bénéficier des attributs (variables) et des comportements (fonctions) de la classe de base dont elle hérite (ou dérive). Vous découvrirez également que les classes dérivées peuvent contenir d’autres éléments permettant de spécialiser la classe de base. Grâce à cette technique, il est donc possible de définir des arborescences (ou hiérarchie) de classes qui regroupent des classes de plus en plus spécialisées. Le polymorphisme s’applique aux fonctions membres des classes et permet à deux objets (appartenant à deux classes différentes) de réagir différemment au même appel de méthode. Cette technique s’utilise conjointement avec l’héritage et représente sans conteste le plus grand apport des langages orientés objet (LOO). Le Chapitre 9 vous permettra de mesurer l’impact de cette technologie dans le cadre des développements à base d’objets. Le C++ présente toutes les caractéristiques d’un langage orienté objet (LOO). Le C++ permet également d’utiliser l’approche procédurale (héritée du C), ce qui constitue un sérieux avantage, puisqu’il est possible de récupérer et de réutiliser tous les outils basés sur le langage C. 7