De manière superficielle, le terme « orienté objet » signifie que l'on organise le logiciel comme une collection d'objets dissociés comprenant à la fois une structure de données - attributs - et un comportement – méthodes - dans une même entité.
Exemple : une voiture peut avoir une certaine couleur et en même temps possède un comportement qui sera le même pour toutes les autres voitures, comme accélérer.
Ce concept est différent de la programmation conventionnelle dans laquelle les structures de données et le comportement ne sont que faiblement associés.
Chaque objet possède une identité et peut être distingué des autres. Deux pommes ayant les mêmes couleur, forme et texture sont des pommes individuelles ; une personne peut manger l'une, puis l'autre. De la même façon, des jumeaux sont deux personnes distinctes, même si elles se ressemblent. Le terme identité signifie que les objets peuvent être distingués grâce à leurs existences inhérentes et non grâce à la description des propriétés qu'ils peuvent avoir. Nous utiliserons l'expression « instance » d'objet pour faire référence à une chose précise, et l'expression « classe » d'objets pour désigner un groupe de choses similaires. En d'autres termes, deux objets sont distincts même si tous leurs attributs (nom, taille et couleur par exemple) ont des valeurs identiques (deux pommes vertes sont deux objets distincts). Par ailleurs, un objet évolue au cours du temps, comme, par exemple, une pomme peut mûrir. Chaque objet possède un état qui correspond à la valeur de ces attributs à un instant donné.
Objet = Identité + Etat + Comportement
.
La classification signifie que les objets ayant la même structure de donnée – attributs - et le même comportement - méthodes - sont regroupés en une classe. Les objets d'une classe ont donc le même type de comportement et les mêmes attributs. En groupant les objets en classe, on abstrait un problème. Les définitions communes (telles que le nom de la classe et les noms d'attributs) sont stockées une fois par classe plutôt qu'une fois par instance. Les méthodes peuvent être écrites une fois par classe, de telle façon que tous les objets de la classe bénéficient de la réutilisation du code. Par exemple, toutes les ellipses partagent les procédures de dessin, de calcul d'aire ou de test d'intersection avec une ligne.
Une classe est un modèle utilisé pour créer plusieurs objets présentant des caractéristiques communes.
.
Chaque objet possède ses propres valeurs pour chaque attribut mais partage noms d'attributs et méthodes avec les autres objets de la classe. Par exemple une classe Voiture peut être définie comme ayant un des attributs couleur et comme une des méthodes freiner ; les objets associées à la classe voiture peuvent être : Mercedes rouge, Clio verte, etc. Ces objets ont le même comportement (freiner). On peut acheter un kilo de pommes vertes calibrées, chacune de ces pommes est un objet unique qui correspond à la classe Pomme avec comme attributs (couleur , calibre).

Rappelons que la notion de variable informatique est identique à la variable mathématique et que la notion de type correspond à l'ensemble de définition. De façon plus concrète, la variable correspond à un emplacement mémoire, et il est nécessaire de connaître son type pour déterminer sa taille.
Un attribut est une valeur de donnée détenue par les objets de la classe. Couleur et Poids sont des attributs des objets relatifs à Voiture. Chaque attribut à une valeur pour chaque instance d'objet. Par exemple, l'attribut Couleur porte la valeur rouge dans l'objet Mercedes alors que pour l'objet Clio, la valeur de l'attribut Couleur est verte. Les instances peuvent avoir des valeurs identiques ou différentes pour un attribut donné. Chaque nom d'attribut est unique à l'intérieur d'une classe. Ainsi, la classe Voiture et la classe Pomme peuvent avoir chacune un attribut Couleur.
Dans une classe, les attributs sont définis par des variables. Les attributs peuvent être considérés comme des variables globales pour chaque objet de cette classe. Comme pour toutes variables, il est nécessaire de connaître le type correspondant et c'est la classe de l'objet qui indique de quel type d'attribut (variable) il s'agit. Chaque objet stocke sa propre valeur pour chacune de ses variables.
Une méthode est une fonction ou une opération qui peut être appliquée aux objets ou par les objets dans une classe. Accélérer et freiner sont des méthodes de la classe Voiture. Tous les objets d'une même classe partagent les mêmes méthodes. Chaque méthode a un objet cible comme argument implicite (c'est l'objet lui-même « this » , elle peut donc accéder à chacun des attributs). Le même nom de méthode peut s'appliquer à des classes différentes, vu que la portée de la méthode est sa classe. Une méthode peut avoir des arguments, en plus de son objet cible.
Avant de créer nos premiers objets, nous allons mettre en œuvre une structure qui représente un nombre complexe. A cette structure, nous allons lui associer des fonctions qui vont respectivement permettre de déterminer le module et l'argument de ce nombre complexe.

Ce programme fonctionne très bien, mais cette approche présente quelques inconvénients ; En effet, nous avons une séparation entre la structure d'une part, et les fonctions associées à cette structure d'autre part, alors que normalement tous ces éléments s'intéressent au même problème, c'est-à-dire, aux traitements des nombres complexes.
Si nous prenons le nom de la fonction module ; ce nom peut aussi bien évoquer le module d'un nombre complexe ou peut-être le module d'un vecteur. Heureusement, la signature de la fonction nous indique qu'il s'agit bien d'une connexion à une structure Complexe.
Enfin, lorsque nous fabriquons des fonctions qui gèrent des structures, il est systématiquement nécessaire de passer en paramètre la structure concernée. Cette façon de procéder présente l'énorme inconvénient d'avoir un temps de réponse conséquent et d'utiliser de la mémoire supplémentaire pour stocker momentanément cette structure sur la pile.
Pour toutes les raisons que nous venons d'évoquer, il serait souhaitable que les fonctions module et argument soient intégrées directement dans la structure. D'une part, le traitement demandé concerne cette structure. Par ailleurs, vus que ces fonctions sont à l'intérieur de la structure, elles peuvent atteindre directement les champs reel et imaginaire. Le fait que tout soit intégré, les champs sont appelés des attributs, les fonctions sont appelées des méthodes.
Vous remarquez que, cette fois-ci, les méthodes ne possèdent pas de paramètres. Tout ce qu'elles ont besoin se situe dans la classe. Les attributs sont directement accessibles aux méthodes (et uniquement par elles d'ailleurs). En fait, les attributs et les méthodes sont sur la même portée, c'est-à-dire, la classe.
Ces méthodes sont là pour permettre la communication avec l'extérieur. Souvent deux cas se présentent :
Il existe d'autres types de méthode comme les constructeurs et les destructeurs. Ces méthodes seront traitées ultérieurement.
Tout ce que nous avons appris sur les fonctions s'applique pour les méthodes. Du point de vue du langage C++, une méthode reste une fonction, sauf qu'elle est intégrée dans une classe.
Dans le langage C++, un objet est une variable, et le nom de la variable représente son identité. Comme il s'agit d'une variable au sens générique du terme, il est donc possible d'avoir des déclarations spécifiques suivant le besoin. Par exemple, nous pouvons avoir besoin ; d'un objet constant (la variable i complexe devrait d'ailleurs être déclarée constante), d'un tableau d'objets, de pointeur d'objet, d'un objet dynamique, etc.

L'encapsulation est le principe qui permet de regrouper les attributs et méthodes au sein d'une classe. Cette notion est aussi associée au dispositif de protection qui permet de contrôler la visibilité d'un attribut ou d'une méthode. En d'autres termes, cela signifie que chaque fois que vous définissez un membre d'une classe ( attribut ou méthode ), vous devez indiquer les droits d'accès quant à l'utilisation de ce membre.
Ce mécanisme d'encapsulation permet surtout de protéger l'objet de toute malveillance externe. Pour cela, la plupart du temps, il faut interdire l'accès direct aux attributs et passer systématiquement par les méthodes.
Par exemple : si l'on désire changer la couleur d'une voiture, cela ne se fait pas par enchantement, il est nécessaire de passer par tout un processus (décaper, poncer, passer plusieurs couches, etc...), et dans ce cas de figure l'attribut couleur ne doit pas être accessible directement.
Comme nous venons de l'évoquer, le changement d'état d'un objet passe nécessairement par la méthode associée. Cela n'a aucun sens de vouloir atteindre directement un attribut.
Il existe trois niveaux de protection :
Par défaut, une structure possède le niveau de protection le plus faible, c'est-à-dire que tous les membres sont publiques. Il faut donc rajouter à notre implémentation les qualificatifs nécessaires pour améliorer la protection et donc respecter le contrat d'encapsulation.

En fait, pour être sûr de respecter le principe d'encapsulation, il est généralement préférable d'utiliser une structure qui est privée par défaut. Il s'agit de la structure class. Dorénavant, nous utiliserons le mot réservé class plutôt que struct.

Lorsque la définition d'une méthode est très courte, il est préférable de l'écrire "inline" comme pour une fonction. Il est impératif, bien entendu, qu'elle soit décrite dans le fichier en-tête. Il est même possible de donner la définition directement dans la déclaration de la classe. Il est toutefois souvent souhaitable de proposer une séparation entre la déclaration et la définition.

La programmation orientée objet est très séduisante. Elle est tellement séduisante que tous les langages de programmation qui sortent actuellement intègrent systématiquement cette philosophie. Ce type de programmation consiste à découper le projet en module. Chacun des modules est représenté par une classe. Au fur et à mesure du développement de projets multiples, nous pouvons nous retrouver avec une multitude de classes. Il peut même arriver que nous développions des classes différentes mais qui portent le même nom. Il faut pouvoir gérer ce genre de situation. Les espaces de nom sont là pour palier à ce problème.
Un espace de nom est un paquetage qui regroupe des classes et des fonctions dans une même entité, généralement représentant le même domaine. Le paquetage fait un peu penser à une bibliothèque. Il peut d'ailleurs être judicieux d'associer un paquetage à une bibliothèque. Le symbole du paquetage est un répertoire. Ainsi pour atteindre un des éléments (classes ou fonctions), il faut le référencer au travers du paquetage. Si deux classes comportent le même nom, la localisation ne pose plus de problème puisqu'elles sont situées dans des paquetages différents ce qui évite tout conflit de nom.
Pour illustrer mes propos, je vous propose de fabriquer un paquetage qui comportera la classe Complexe ainsi que deux fonctions paire et impaire. Nous nommerons ce paquetage Mathématique.
Le programme principal se situe à l'extérieur du paquetage. Il sera donc nécessaire de référencer le paquetage pour atteindre la classe et les fonctions de parités.
Pour définir un nouveau paquetage (espace de nom), il suffit d'utiliser le mot réservé « namespace » et de placer entre les accolades tous les éléments qui font partis de ce paquetage. Il est possible de spécifier le même paquetage dans plusieurs fichiers. Il suffit, tout simplement d'indiquer l'espace de nom et, à chaque fois, d'introduire les éléments concernés entre les accolades.



La déclaration d'un membre d'espace de noms est cachée dans son espace de nom. Ainsi, la classe Complexe est cachée dans l'espace de nom Mathematique. A moins de préciser au compilateur dans quel espace de noms rechercher une déclaration, le compilateur cherche uniquement dans la portée locale.
Lorsque nous définissons une méthode, nous devons qualifier la classe qui gère cette méthode grâce à l'opérateur de portée « :: ». De la même façon, nous devons qualifier l'espace de nom pour atteindre l'élément qui se trouve à l'intérieur, de nouveau grâce au même opérateur de portée « :: ».
Avec cette écriture, il n'est plus possible d'avoir de conflit, puisque nous précisons bien que nous prenons tel élément de tel espace de noms. Lorsque nous sommes sûr de ne pas avoir de conflits pour certains éléments, il est quand même embêtant d'avoir une syntaxe aussi lourde. Il serait préférable d'indiquer dès le départ les éléments que nous souhaitons utiliser. Vous devez alors, grâce au mot réservé « using » lister les éléments que vous souhaitez atteindre directement sans le préfixe de l'espace de nom.
Finalement, il est peu fréquent d'avoir des conflits. Il est quand même souhaitable de prévoir au cas où. Cela ne coûte pas grand-chose. Toutefois, si nous sommes sûr qu'aucun des éléments de l'espace de noms ne présente de conflit avec l'extérieur, il serait plus intéressant de les rendre accessible en spécifiant le paquetage tout entier.
En C++, nous pouvons utiliser un espace de noms non nommé pour déclarer une entité locale à un fichier. Cela sous-entend que cette entité ne sera plus du tout accessible depuis un autre fichier. Cette entité est donc privée. Elle ne peut être utilisée que par les autres entités du même fichier.
En fait, tous les composants de la bibliothèque standard C++ sont déclarés et définis dans un espace de nom appelé « std ». Toutefois, avec la compilation conditionnelle, cet espace de nom n'est pas pris en compte lorsque nous effectuons l'inclusion suivante :
#include <iostream.h>
Si nous désirons que l'espace de nom « std » soit effectivement intégré, il faut plutôt préciser l'inclusion suivante :
#include <iostream>
Du coup, il sera nécessaire de préfixer chacun des éléments pour pouvoir les atteindre. Ainsi, pour atteindre l'objet « cout », il sera nécessaire d'écrire « std ::cout ». Du coup, pour éviter cette spécification, il vaut mieux utiliser la directive « using ». En fait, nous utiliserons fréquemment la syntaxe suivante :
#include <iostream>
using namespace std ;