C++

ÔĽŅ
C++
C++
C plus plus.svg

Apparu en 1983[1] (dernière révision en 2008)
Auteur Bjarne Stroustrup
Paradigme générique, orienté objet, procédural
Typage statique, unsafe, nominatif
Normes ISO/CEI 14882:1998 (Standard C++)
ISO/CEI 14882:2003
Influencé par C, Simula, Ada 83, Algol 68, CLU, ML
A influencé Ada 95, C#, PHP, D, Javascript, Java, X++
Implémentations GNU Compiler Collection, Microsoft Visual C++, Borland C++ Builder, XCode Tools

Le C++ est un langage de programmation permettant la programmation sous de multiples paradigmes comme la programmation procédurale, la programmation orientée objet et la programmation générique. C++ est actuellement le 3e langage le plus utilisé au monde[2]. Le langage C++ n'appartient à personne et par conséquent n'importe qui peut l'utiliser sans besoin d'une autorisation ou obligation de payer pour avoir le droit d'utilisation.

Sommaire

Histoire

Bjarne Stroustrup, l'inventeur de C++

Bjarne Stroustrup a d√©velopp√© C++ au cours des ann√©es 1980, alors qu'il travaillait dans le laboratoire de recherche Bell d'AT&T. Il s'agissait en l'occurrence d'am√©liorer le langage C. Il l'avait d'ailleurs nomm√© C with classes (¬ę C avec des classes ¬Ľ). Les premi√®res am√©liorations se concr√©tis√®rent donc par la prise en charge des classes, ainsi que par de nombreuses autres fonctionnalit√©s comme les fonctions virtuelles, la surcharge des op√©rateurs, l'h√©ritage (simple ou multiple), les ¬ę templates ¬Ľ, la gestion des exceptions, etc.

Le langage C++ est normalisé par l'ISO. Sa première normalisation date de 1998 (ISO/CEI 14882:1998), sa dernière de 2003 (ISO/CEI 14882:2003). La normalisation de 1998 standardise la base du langage (Core Language) ainsi que la bibliothèque standard de C++ (C++ Standard Library).

En langage C, ++ est l'op√©rateur d'incr√©mentation, c'est-√†-dire l'augmentation de la valeur d'une variable de 1. C'est pourquoi C++ porte ce nom : cela signifie que C++ est un niveau au-dessus du C. Il existe de nombreuses biblioth√®ques C++ en plus de celle qui est incluse dans la norme. Par ailleurs, C++ permet l'utilisation de l'ensemble des biblioth√®ques C existantes.

Fonctionnalités introduites par C++

On peut consid√©rer que C++ ¬ę est du C ¬Ľ avec un ajout de fonctionnalit√©s. Une remarque importante est √† faire cependant : certains programmes syntaxiquement corrects en C ne le sont pas en C++.

Les fonctionnalit√©s ajout√©es sont :

  • les d√©clarations reconnues comme instructions (repris dans C99) ;
  • les op√©rateurs new et delete pour la gestion d'allocation m√©moire ;
  • le type de donn√©es bool (bool√©en) ;
  • les r√©f√©rences ;
  • le mot cl√© const pour d√©finir des constantes (repris par C √† la fin des ann√©es 1980) ;
  • les fonctions inline (repris dans C99) ;
  • les param√®tres par d√©faut dans les fonctions ;
  • les r√©f√©rentiels lexicaux (Espace de noms) et l'op√©rateur de r√©solution :: ;
  • les classes, ainsi que tout ce qui y est li√© : l'h√©ritage, les fonctions membres, les fonctions membres virtuelles, les constructeurs et le destructeur ;
  • la surcharge des op√©rateurs ;
  • les templates ;
  • la gestion d'exceptions ;
  • l'identification de type pendant l'ex√©cution (RTTI : run-time type information) ;
  • le commentaire sur une ligne introduit par ¬ę // ¬Ľ (existant dans BCPL, repris dans C99).

La compilation d'un programme en C++ effectue √©galement un contr√īle plus minutieux sur le typage.

Histoire de C++

Stroustrup a commenc√© √† travailler sur C avec classes en 1979. L'id√©e de cr√©er un nouveau langage vient de l'exp√©rience en programmation de Stroustrup pour sa th√®se de doctorat. Stroustrup trouvait que Simula avait des fonctionnalit√©s tr√®s utiles pour le d√©veloppement de gros programmes mais qu'il √©tait trop lent pour √™tre utilis√© en pratique (cela √©tait d√Ľ √† un probl√®me d'impl√©mentation du compilateur Simula), tandis que BCPL √©tait rapide mais de trop bas niveau et non adapt√© au d√©veloppement de gros logiciels. Quand Stroustrup commen√ßa √† travailler aux laboratoires Bell, on lui demanda d'analyser le noyau UNIX en vue de faire du calcul distribu√©. Se rappelant sa th√®se, Stroustrup commen√ßa √† am√©liorer le langage C avec des fonctionnalit√©s similaires √† celle de Simula. C fut choisi parce qu'il est rapide, portable et d'usage g√©n√©ral. En outre, il √©tait une bonne base pour le principe original et fondateur de C++ : ¬ę vous ne payez pas pour ce que vous n'utilisez pas ¬Ľ. D√®s le d√©part, le langage ajoutait √† C la notion de classe (avec encapsulation des donn√©es), de classe d√©riv√©e, de v√©rification des types renforc√©s (typage fort), d'¬ę inlining ¬Ľ, et d'argument par d√©faut.

Comme Stroustrup développait C avec classes, il écrivit CFront, un compilateur qui générait du code source C à partir de code source C avec classes. La première commercialisation se fit en octobre 1985.

En 1983, le nom du langage passa de C avec classes √† celui de ¬ę C++ ¬Ľ. Parmi les nouvelles fonctionnalit√©s qui furent ajout√©es au langage, il y avait les fonctions virtuelles, la surcharge des op√©rateurs et des fonctions, les r√©f√©rences, les constantes, le contr√īle du typage am√©lior√© et les commentaires en fin de ligne. En 1985 fut publi√©e la premi√®re √©dition de The C++ programming Language, apportant ainsi une r√©f√©rence importante au langage qui n'avait pas encore de standard officiel. En 1989, c'est la sortie de la version 2.0 de C++. Parmi les nouvelles fonctionnalit√©s, il y avait l'h√©ritage multiple, les classes abstraites, les fonctions membres statiques, les fonctions membres constantes, et les membres prot√©g√©s. En 1990, The Annotated C++ Reference Manual (¬ę ARM ¬Ľ) fut publi√© apportant les bases du futur standard. Les ajouts de fonctionnalit√©s tardifs qu'il comportait couvraient les mod√®les, les exceptions, les espaces de noms, les nouvelles conversions et le type bool√©en.

Comme le langage C++ évoluait, la bibliothèque standard évoluait de concert. La première addition à la bibliothèque standard de C++ concernait les flux d'entrées/sorties qui apportaient les fonctionnalités nécessaires au remplacement des fonctions C traditionnelles telles que printf et scanf. Ensuite, parmi les additions les plus importantes, il y avait la Standard Template Library.

Apr√®s des ann√©es de travail, un comit√© r√©unissant l'ANSI et l'ISO standardisa C++ en 1998 (ISO/CEI 14882:1998), l'ann√©e o√Ļ le comit√© de standardisation se r√©unissait √† Sophia Antipolis dans le sud de la France. Pendant quelques ann√©es apr√®s la sortie officielle du standard, le comit√© traita le rapport de probl√®mes et publia une version corrig√©e du standard C++ en 2003.

Personne ne possède le langage C++. Il est libre de droit. Le document de standardisation n'est quant à lui pas disponible gratuitement.

La bibliothèque standard (C++ standard library)

La bibliothèque standard du C++ est en grande partie un sur-ensemble des fonctions disponibles dans la bibliothèque standard du C. Elle englobe la Standard Template Library (STL) qui met à la disposition du programmeur des outils puissants comme les collections (conteneurs) et les itérateurs.

À l'origine, la STL était une bibliothèque développée par Alexander Stepanov qui travaillait pour Hewlett-Packard. Dans la norme, celle-ci n'est pas appelée STL, car elle est considérée comme faisant partie de la bibliothèque standard du C++. Toutefois, beaucoup de personnes l'appellent encore de cette manière pour distinguer d'une part, les fonctions d'entrées/sorties comprises dans cette bibliothèque et, d'autre part, celles fournies par la bibliothèque C.

Comme en C, l'utilisation d'une bibliothèque se fait par l'intermédiaire de la directive #include (suivie du nom du fichier d'en-tête).

La programmation orientée objet en C++

C++ utilise les concepts de la programmation orient√©e objet et permet entre autres :

L'encapsulation en C++

L'encapsulation permet de faire abstraction du fonctionnement interne (c'est-√†-dire, la mise en Ňďuvre) d'une classe et ainsi de ne se pr√©occuper que des services rendus par celle-ci. C++ met en Ňďuvre l'encapsulation en permettant de d√©clarer les membres d'une classe avec le mot r√©serv√© public, private ou protected. Ainsi, lorsqu'un membre est d√©clar√© :

  • public, il sera accessible depuis n'importe quelle fonction.
  • private, il sera uniquement accessible d'une part, depuis les fonctions qui sont membres de la classe et, d'autre part, depuis les fonctions autoris√©es explicitement par la classe (par l'interm√©diaire du mot r√©serv√© friend).
  • protected, il aura les m√™mes restrictions que s'il √©tait d√©clar√© private, mais il sera en revanche accessible par les classes filles.

C++ n'impose pas l'encapsulation des membres dans leurs classes. On pourrait donc d√©clarer tous les membres publics, mais en perdant une partie des b√©n√©fices apport√©s par la programmation orient√©e objet. Il est de bon usage de d√©clarer toutes les donn√©es priv√©es, ou au moins prot√©g√©es, et de rendre publiques les m√©thodes agissant sur ces donn√©es. Ceci permet de cacher les d√©tails de la mise en Ňďuvre de la classe.

¬ę Hello, world ¬Ľ

Voici l'exemple de Hello world donn√© dans The C++ Programming Language, Third Edition[3] de Bjarne Stroustrup :

#include<iostream>
 
int main()
{
    std::cout << "Hello, new world!\n";
}

Une importante notion de C++ sont les espaces de noms (namespaces). Dans un espace de noms sont d√©finis des noms de fonctions et de variables. Ce m√©canisme permet de r√©soudre les ambigu√Įt√©s lorsque plusieurs variables provenant de diff√©rents composants sont homonymes. Pour recourir √† une fonction d'un espace de nom, l'op√©rateur de r√©solution de port√©e ¬ę :: ¬Ľ est utilis√©.

std::cout

Ce code source fait appel √† la variable globale cout d√©finie dans l'espace de nom standard (std). Il est possible de sp√©cifier un espace de nom pr√©cis √† utiliser afin d'√©viter d'avoir √† recourir √† l'op√©rateur de r√©solution de port√©e. Pour cela, le mot cl√© using est utilis√© avec cette syntaxe :

using namespace nom_du_namespace;

Ainsi, pour utiliser la variable cout d√©finie dans le namespace standard sans utiliser l'op√©rateur de r√©solution de port√©e, il est possible d'√©crire :

using namespace std;

Cela est valable pour tous les espaces de noms. Cette instruction se place en g√©n√©ral avant le d√©but du code source proprement dit :

#include <iostream>
using namespace std;
int main()
{
    cout << "Hello, new world!" << endl;
    return 0;
}

Déclaration de classe

Exemple de la d√©claration de la classe MessageInternet comportant des attributs priv√©s et des m√©thodes publiques dont le constructeur 'MessageInternet' :

 class MessageInternet
 {
  private:
   string m_sSujet;
   string m_sExpediteur;
   string m_sDestinataire;
  public:
   MessageInternet (string sujet, string expediteur, string destinataire);
   string GetSujet () const;
   string GetExpediteur () const;
   string GetDestinataire () const;
 };

Déclaration de templates

√Ä quoi servent les templates ?

Les templates permettent d'écrire des fonctions et des classes en paramétrant le type de certains de leurs constituants (type des paramètres ou type de retour pour une fonction, type des éléments pour une classe collection par exemple). Les templates permettent d'écrire du code générique, c'est-à-dire qui peut servir pour une famille de fonctions ou de classes qui ne diffèrent que par la valeur de ces paramètres.

Paramètres des templates

Les param√®tres peuvent √™tre de diff√©rentes sortes :

  • Types simples : class, struct, types √©l√©mentaires comme int, float, etc.
  • Tableaux de taille constante, dont la taille, d√©duite par le compilateur, peut √™tre utilis√©e dans l'instanciation du template.
  • Constantes scalaires, c'est-√†-dire de type d√©rivant des entiers (int, long, bool), mais pas double ou float (car leur repr√©sentation binaire ne fait pas partie de la norme du langage C++).
  • Templates : La d√©finition d'un template peut √™tre pass√©e √† un template, ce qui permet notamment de s'appuyer sur la d√©finition abstraite, par exemple, d'un conteneur.
  • Pointeurs ou r√©f√©rences, √† condition que leur valeur soit d√©finie √† l'√©dition de liens.
  • Fonction membre, dont la signature et la classe doivent √™tre aussi pass√©es en param√®tres.
  • Membre d'une classe, dont le type et la classe doivent √™tre aussi pass√©s en param√®tres du template.

Pourquoi utiliser des templates ?

En programmation, il faut parfois écrire de nombreuses versions d'une même fonction ou classe suivant les types de données manipulées.

Par exemple, un tableau de int ou un tableau de double sont très semblables, et les fonctions de tri ou de recherche dans ces tableaux sont identiques, la seule différence étant le type des données manipulées.

En r√©sum√©, l'utilisation des templates permet de ¬ę param√©trer ¬Ľ le type des donn√©es manipul√©es.

Avantages à utiliser des templates

  • √©critures uniques pour les fonctions et les classes.
  • moins d'erreurs dues √† la r√©√©criture.
  • performances am√©lior√©es gr√Ęce a la sp√©cialisation en fonction des types de donn√©es.

Exemple de templates

Dans la biblioth√®que standard C++, on trouve de nombreux templates. On citera √† titre d'exemple, les entr√©es/sorties, les cha√ģnes de caract√®res ou les conteneurs. Les classes string, istream, ostream et iostream sont toutes des instanciations de type char.

Les fonctions de recherche et de tri sont aussi des templates écrits et utilisables avec de nombreux types.

// La fonction template Max peut être appelée avec tout type copiable
// et comparable avec l'opérateur <.
template <typename T> T Max(T a, T b)
{
    return a < b ? b : a;
}
 
# include <string>
int main()  // fonction main
{
    int i = Max(3, 5);
    char c = Max('e', 'b');
    std::string s = Max(std::string("hello"), std::string("world"));
    float f = Max<float>(1, 2.2f);
    return 0;
}

Dans la ligne float f = Max<float>(1, 2.2f), on doit explicitement donner le type float pour le type paramétré T car le compilateur ne déduit pas le type de T lorsqu'on passe en même temps un int (1) et un float (2.2f).

Spécialisation des templates

Un template donn√© peut avoir plusieurs instanciations possibles selon les types donn√©s comme param√®tres. Si un seul param√®tre est sp√©cialis√©, on parle de sp√©cialisation partielle. Ceci permet par exemple :

  • De choisir un type de calcul selon qu'un type est un entier, un nombre flottant, une cha√ģne de caract√®res, etc. Sp√©cialisons l'exemple pr√©c√©dent pour le cas des pointeurs de chaines de caract√®res :
template <> const char * Max(const char * a, const char * b)
{
    return (strcmp( a, b ) > 0) ? a : b;
}
  • D'effectuer au moment de la compilation des calculs arithm√©tiques, si et seulement si tous les arguments sont connus √† ce moment. Un exemple classique est le calcul de la fonction factorielle:
template< size_t N >
struct CalcCompileTime
{
    static size_t Fact = N * CalcCompileTime< N - 1 >::Fact ;
};
 
template<0>
struct CalcCompileTime<0>
{
    static size_t Fact = 1 ;
};

SFINAE

Le mécanisme décrit par l'abréviation SFINAE (Substitution Failure Is Not An Error) permet de surcharger un template par plusieurs classes, même certaines spécialisations, par exemple, ne peuvent pas être utilisées pour tous les paramètres de templates. Le compilateur, lors de la substitution, ignore alors les instantiations inapplicables, au lieu d'émettre une erreur de compilation.

Le polymorphisme et les méthodes virtuelles en C++

Le polymorphisme est mis en Ňďuvre √† l'aide du m√©canisme des m√©thodes virtuelles en C++. Lorsqu'une m√©thode virtuelle est appel√©e, l'impl√©mentation de la m√©thode ex√©cut√©e est choisie en fonction du type r√©el de l'objet. L'appel n'est donc r√©solu qu'√† l'ex√©cution, le type de l'objet ne pouvant pas - a priori - √™tre connu √† la compilation. Un mot cl√© est alors introduit : virtual. Ce mot cl√© est plac√© devant la d√©claration de la m√©thode.

Le mot clé virtual, placé devant le prototype de la fonction, indique au compilateur que la fonction est susceptible d'être redéfinie dans une classe dérivée. Il suffit alors de dériver une classe et de définir une nouvelle fonction de même signature (même nom, paramètres compatibles - voir la notion de covariance). Ainsi l'appel de cette fonction sur un objet dont on ignore le type, mais accédé en tant qu'objet de la classe de base, pourra donner lieu à l'appel de la fonction définie dans la classe dérivée.

Il est généralement conseillé d'utiliser le mot clé virtual devant la déclaration du destructeur de la classe de base, afin que celui des sous-classes soit appelé également lorsque le programme utilise un pointeur d'instance de la classe de base au lieu d'un pointeur d'instance de la classe dérivée si et seulement si la classe de base peut être utilisée pour manipuler des classes dérivées.

Ce type de polymorphisme est dit dynamique. Le m√©canisme de la surcharge est un polymorphisme statique. Dans les deux cas il faut appliquer une logique (par exemple : le nombre et le type des param√®tres) pour r√©soudre l'appel. Dans le cas de la surcharge, la logique peut √™tre enti√®rement calcul√©e √† la compilation. Ce calcul permet des optimisations rendant le polymorphisme statique "plus rapide" que sa version dynamique. La liaison dynamique de m√©thodes issues du m√©canisme des m√©thodes virtuelles induit souvent une table cach√©e de r√©solution des appels. Cette table cach√©e des m√©thodes augmente le temps n√©cessaire √† l'appel de m√©thode √† l'ex√©cution par l'ajout d'une indirection suppl√©mentaire.

Le choix entre liaison dynamique et surcharge (polymorphisme dynamique et statique) est typiquement un problème de calculabilité des appels, ayant souvent pour conséquence finale un choix entre expressivité et performance.

Bibliographie

Construction

Un programme C++ peut √™tre produit avec des outils qui automatisent le processus de construction. Les plus utilis√©s sont :

  • Make
  • Ant (g√©n√©ration portable en XML)
  • SCons (g√©n√©ration portable en Python).
  • CMake g√©n√©ration de Makefile portable

Environnements de développement

Compilateurs C++

Bibliothèques C++

Notes et références

Voir aussi

Sur les autres projets Wikimedia :

Liens externes


Wikimedia Foundation. 2010.

Contenu soumis à la licence CC-BY-SA. Source : Article C++ de Wikipédia en français (auteurs)


Share the article and excerpts

Direct link
… Do a right-click on the link above
and select ‚ÄúCopy Link‚ÄĚ

We are using cookies for the best presentation of our site. Continuing to use this site, you agree with this.