Beruflich Dokumente
Kultur Dokumente
en C++
Chapitre 1 : Notions de base
Auteur : A. MOHAMMEDI
Les classes en C++
08/12/2019 INSIM TO 2
Les classes
L'en-tête : mot clé class suivi du nom de la classe.
Le corps : mis entre accolade, il est constitué des différentes
données et méthodes membres de la classe.
Une définition de classe est terminée par un point-virgule ou
par une liste de déclaration.
Exemple :
l'en-tête de la classe
class personne
{
string nom; corps de la classe
string prenom;
...}
;
08/12/2019 INSIM TO 3
Les données membres d'une classe
Les données membres d'une classe sont
déclarées de la même façon que les variables.
Elles sont incluses dans le corps de la classe.
Elles sont aussi dites : attributs de la classe.
Exemple :
#include <string>
class personne {
string nom; nom, prenom, age sont les
string prenom; données membres de la
classe personne
short int age;
};
08/12/2019 INSIM TO 4
Les données membres d'une classe
08/12/2019 INSIM TO 5
Les fonctions membres d'une classe
string getNom();
string getPrenom();
string getAge() {return age;}
};
08/12/2019 INSIM TO 6
Les fonctions membres d'une classe
08/12/2019 INSIM TO 7
Les fonctions membres d'une classe
Exemple :
Implémentation des fonctions getNom() et
getPrenom() à l'extérieur de la classe se fait
comme suit :
//utilisation de l'opérateur :: pour accéder au nom de la
fonction
string personne::getNom(){ return nom;}
string personne::getPrenom()
{return Prenom;}
08/12/2019 INSIM TO 8
Objets de classe (instanciation simple)
08/12/2019 INSIM TO 9
Objets de classe (instanciation simple)
08/12/2019 INSIM TO 10
Accès à un membre de classe
08/12/2019 INSIM TO 11
Masquage d'information
08/12/2019 INSIM TO 12
Les classes et fonctions amies
08/12/2019 INSIM TO 14
Les classes et fonctions amies
Exemple :
La fonction non membre affiche() qui permet d'afficher les informations
relatives à un objet de la classe personne :
void affiche (const personne & p)
{
!
cout << "Le nom : \t" << p.nom << endl;
cout << "Age :\t" << p.age << endl;
}
Solution :
– Définir la fonction affiche() comme amie de la classe personne,
comme suit :
class personne {
friend void affiche (const personne &);
...//suite du corps de la classe
};
08/12/2019 INSIM TO 15
Déclaration versus définition de classe
Déclaration : introduit le nom de la classe dans
le programme et indique que ce nom se réfère
à un type classe :
class nom_classe;
08/12/2019 INSIM TO 17
Déclaration versus définition de classe
08/12/2019 INSIM TO 18
Fonctions membres en ligne (inline)
08/12/2019 INSIM TO 20
Les fonctions membres const
08/12/2019 INSIM TO 21
Les fonctions membres const
08/12/2019 INSIM TO 22
Les fonctions membres const
Exemple :
class personne {
public :
string getNom () const;
int getAge() const {return age;}
...};
//définition de la fonction const getNom() à
l'extérieur de la classe
String personne::getNom()const
{return nom;}
08/12/2019 INSIM TO 23
Le pointeur implicite this
08/12/2019 INSIM TO 27
Le constructeur par défaut
Il peut ne pas être défini explicitement à condition
qu’aucun autre constructeur ne soit défini dans la
classe
Le constructeur par défaut d'une classe porte le même
nom que sa classe, et ne spécifie aucun argument
– Syntaxe :
nom_classe();
08/12/2019 INSIM TO 28
Le constructeur avec arguments
08/12/2019 INSIM TO 29
Le constructeur de copie
L'initialisation d'un objet de classe avec un autre objet
de sa classe s'appelle initialisation membre à membre
par défaut.
Le concepteur de la classe peut fournir un
constructeur de copie de classe explicite.
– Syntaxe :
nom_classe(const nom_classe & rhs);
Il est invoqué chaque fois qu'un objet de classe est
initialisé avec un autre objet de sa classe.
Il est nécessaire de le définir lorsque qu'on a dans la
classe des données membres de type pointeur.
08/12/2019 INSIM TO 30
Exemples de constructeurs
Exemple : Soit la classe personne suivante :
class personne {
public :
string nom;
string prenom;
int age; Le constructeur par défaut
personne () { }
personne (string str_n, string str_p, int i)
{
nom = str_n;
prenom = str_p; Le constructeur avec
age = i; arguments
}
};
08/12/2019 INSIM TO 31
Exemples de constructeurs
Exemple : On peut redéfinir le constructeur par défaut et le
constructeur avec arguments à l'aide de listes d'initialisation
comme suit :
class personne { Le constructeur par
public : défaut avec des valeurs
string nom; initiales pour chaque
Le constructeur avec
string prenom; donnée membre
arguments plus
int age; efficace
personne (): nom ("x"), prenom ("y"), age (18)
{}
personne (string str_n, string str_p, int i) :
nom (str_n), prenom (str_p), age (i) {}
};
08/12/2019 INSIM TO 32
Exemples de constructeurs
Exemple :constructeur de copie
class personne {
public :
…
personne (const personne &rhs)
{ if (&rhs != this)
{
nom = rhs.nom;
prenom = rhs.prenom
age = rhs.age;
}
}
};
08/12/2019 INSIM TO 33
Exemples de construction
08/12/2019 INSIM TO 34
Affectation d'objets de classe
L'affectation d'un objet de classe par un autre objet de sa classe
est gérée par l'affectation membre à membre par défaut.
Création implicite pour chaque classe de l'opérateur
d'affectation de copie.
Pour la classe personne précédente, l'opérateur ressemble à ce
qui suit :
inline personne& operator= (const personne &rhs)
{
nom = rhs.nom;
age = rhs.age;
return *this;
}
08/12/2019 INSIM TO 35
Affectation d'objets de classe
08/12/2019 INSIM TO 36
Destruction d'objets de classe
Le destructeur des objets est la fonction inverse du
constructeur
– Le constructeur permet l'acquisition automatique de
ressources
allocation de la mémoire,
acquisition d'une ressource UC,
d’un fichier, etc.
– Le destructeur permet la désallocation automatique ou la
libération d'une ressource associée à un objet de classe sur
le point de terminer sa durée de vie
Le destructeur spécifie le comportement d’un objet en
fin de vie
08/12/2019 INSIM TO 37
Destruction d'objets de classe
08/12/2019 INSIM TO 38
Programmation orientée objet
en C++
Chapitre 2 : Héritage & polymorphisme
Auteur : N. TAMANI
L’héritage entre classes
08/12/2019 INSIM TO 40
Différents types d'héritage
L'héritage de module : c'est une simple réutilisation
de code par copie des informations de la classe
parente vers la classe dérivée.
– Exemple : construire une classe file (fifo) à l'aide d'une
classe vecteur. L'héritage des informations du vecteur dans
la file, mais non pas le comportement, car ce dernier n'est
pas opportun pour la file.
La composition : une forme d'héritage de module
(implémentation de la relation d’agrégation entre
classes)
08/12/2019 INSIM TO 41
Différents types d'héritage
L’héritage simple
L’héritage multiple
L’héritage virtuel
L’héritage abstrait
Le polymorphisme : corollaire à l’héritage
La composition
08/12/2019 INSIM TO 43
Implémentation de l'héritage en C++
La syntaxe générale pour spécifier l’héritage entre classes est :
class derived : liste_de_dérivation
{
//... définition de la classe dérivée
};
derived : c'est le nom de la classe dérivée;
liste_de_dérivation : c'est une liste formée de
access_specificator base_class séparés par des virgules;
base_class : est le nom de la classe de base;
Les classes spécifiées dans la liste de dérivation doivent être définies
avant d'être utilisées comme des classes de base;
08/12/2019 INSIM TO 44
Implémentation de l'héritage en C++
access_specificator : un modificateur qui peut
être :
– public : d'où l'héritage public (héritage de sous-
type);
– protected : d'où l'héritage protégé;
– private : d'où l'héritage privé.
Le spécificateur indique la propagation de
l’héritage en termes de droits d'accès aux
données et fonctions membres de la classe de
base dans la classe dérivée :
08/12/2019 INSIM TO 45
Implémentation de l'héritage en C++
08/12/2019 INSIM TO 46
L’héritage simple (unique)
Un héritage simple est une dérivation de classe
dans laquelle chaque classe dérive (sous
classe) d'une seule et unique classe de base
(super classe).
Personne
Les membres communs Membres de la
aux classes étudiant et classe personne
enseignant sont mis dans
la classe personne
Étudiant Enseignant
Membres de la Membres de la
classe étudiant classe enseignant
08/12/2019 INSIM TO 47
L’héritage simple (unique)
08/12/2019 INSIM TO 48
Construction des objets dans l'héritage simple
La règle générale :
– Instancier un objet de la classe dérivée déclenche
un processus d'appel au constructeur de la classe
de base, puis enfin le constructeur de la classe
dérivée concernée.
Chaque objet de la classe dérivée possède un
sous objet de sa classe de base.
08/12/2019 INSIM TO 49
Construction des objets dans l'héritage simple
1.Création du sous
objet personne
Personne
Étudiant
2. Création de l’objet
étudiant
08/12/2019 INSIM TO 50
Instanciation par défaut
08/12/2019 INSIM TO 52
Instanciation avec arguments
Exemple :
class personne {
public :
//...
personne (string n, string p, int a) :
nom (n), prenom (p), age (a) {}
//...}; Appel explicite du
class etudiant : public personne { constructeur avec
public : arguments de la classe
personne
int anne_etud;
etudiant (string ne, string pe, int ae, int
anne) :
personne (ne, pe, ae),
anne_etud (an) { }
//...};
08/12/2019 INSIM TO 53
Accès aux membres de la classe de base
Les membres publics et protégés hérités de la classe de base
peuvent être accédés directement comme s'ils étaient membres
de la classe dérivée.
Une exception : Quand la désignation du membre de la classe
de base est réutilisé dans la classe dérivée.
– Exemple : Priorité, lors des
Réutilisation invocations
de la même
class personne { non qualifiées,
désignation dans laà la fonction
classe dérivée
public : redéfinie dans la classe dérivée
void se_deplacer () {//à pied}
//...};
class etudiant : public personne {
public :
void se_deplacer () {//par bus}
//...};
08/12/2019 INSIM TO 54
Accès aux membres de la classe de base
08/12/2019 INSIM TO 55
Destruction des objets dans l’héritage
08/12/2019 INSIM TO 56
Destruction des objets dans l’héritage
1. Destruction de l’objet
étudiant
Personne
Étudiant
Étudiant
2. Destruction du sous
objet personne
08/12/2019 INSIM TO 57
Le polymorphisme
08/12/2019 INSIM TO 58
Le polymorphisme
08/12/2019 INSIM TO 59
Conséquence du Polymorphisme
08/12/2019 INSIM TO 60
Conséquence du Polymorphisme
Exemple : la fonction se_deplacer() dans les classes
personne et étudiant :
class personne {
public :
void se_deplacer () {//à pied}
//...};
class etudiant : public personne {
public :
void se_deplacer () {//par bus}
//...};
Quelle est la fonction à invoquer dans :
p->se_deplacer();
?
08/12/2019 INSIM TO 61
Conséquence du Polymorphisme
Solutions :
1. La solution par défaut
2. Les fonctions virtuelles
La solution par défaut : le compilateur résout
le conflit en imposant que la fonction appelée
soit celle définie dans le type du pointeur (ou
référence);
– Dans notre cas : c'est personne::se_deplacer()
qui sera invoquée;
08/12/2019 INSIM TO 62
Le Polymorphisme et les fonctions virtuelles
08/12/2019 INSIM TO 63
Le Polymorphisme et les fonctions virtuelles
08/12/2019 INSIM TO 64
Le Polymorphisme et les fonctions virtuelles
La classe dérivée peut :
– soit fournir sa propre version de la fonction, qui devient
l'instance active pour cette classe;
– soit hériter de la version de la classe de base.
Le mécanisme de fonctions virtuelles ne fonctionne
correctement qu'avec les pointeurs et références.
Le mécanisme virtuel ne permet pas d'appeler une
fonction membre de la classe dérivée non définie
dans sa classe de base
Les données membres de la classe dérivée ne sont pas
accessibles via un pointeur ou référence vers la classe
de base
08/12/2019 INSIM TO 65
Le polymorphisme et les destructeurs
Soit le pointeur p :
personne *p = new etudiant;
p est un pointeur de la classe de base pointant un
objet de la classe dérivée.
L’instruction : delete (p);
!
le destructeur de la classe personne qui sera appelé
pour détruire un objet etudiant;
Donc, il est plus que nécessaire de définir aussi le
destructeur de la classe de base comme étant virtuel.
08/12/2019 INSIM TO 66
Le polymorphisme et les destructeurs
08/12/2019 INSIM TO 67
Héritage multiple
08/12/2019 INSIM TO 68
Héritage multiple
Exemple : Un amphibien est à la fois un
animal aquatique et terrestre :
Terrestre Aquatique
Membres de la Membres de la
classe terrestre classe aquatique
Amphibien
Membres de la
classe amphibien
08/12/2019 INSIM TO 69
Héritage multiple
L'implémentation de la classe Amphibien :
class Amphibien : public Aquatique,
public Terrestre
{//... Les membres de classe Amphibien
};
Une classe de base ne peut apparaître dans une liste
d'héritage multiple que si sa définition a déjà été
fournie
Pas de limitation du nombre de classes de base qui
peuvent apparaître dans une liste de dérivation
La classe dérivée contient un sous objet de chacune
de ses classes de base.
08/12/2019 INSIM TO 70
Invocation des constructeurs et destructeurs
Le processus de création d'un objet d'une classe qui
dérive de plusieurs classes de base est similaire au
processus vu pour l'héritage simple.
Invocation de tous les constructeurs des classes de
base dans le même ordre de leurs déclarations dans la
liste de dérivation.
1.Création du sous
objet Aquatique
08/12/2019 INSIM TO 71
Invocation des constructeurs et destructeurs
08/12/2019 INSIM TO 72
Membres hérités de plusieurs classes
L'accès aux membres (public et protected) dans le cas
d'un héritage multiple est identique à celui vu pour
l'héritage simple.
Possibilité de conflits lorsqu'on accède à des
membres de même noms qui sont hérités à partir de
plusieurs classes de base.
Il faut utiliser les noms qualifiés pour rendre l'accès
non ambiguë.
Les fonctions de même nom héritées à partir de
plusieurs classes de base ne forment pas un jeu de
fonctions surchargées dans la classe dérivée.
08/12/2019 INSIM TO 73
Les fonctions virtuelles et l'héritage multiple
08/12/2019 INSIM TO 74
Conséquence de l’héritage multiple
Exemple : Les classes aquatique et terrestre dérivent
toutes les deux de la classe animal :
Animal
Membres de la
classe animal
Terrestre Aquatique
Membres de la Membres de la
classe terrestre classe aquatique
Amphibien
Membres de la
classe amphibien
08/12/2019 INSIM TO 75
Conséquence de l’héritage multiple
08/12/2019 INSIM TO 76
L’héritage virtuel
Résolution du problème :
– Si le comportement obtenu par cette forme d'héritage est
celui désiré utilisation des noms qualifiés pour les accès;
– Sinon utilisation du mécanisme de l'héritage virtuel.
Définition : dans l'héritage virtuel un seul sous objet
partagé de la classe de base racine est hérité, quel que
soit le nombre d'apparition de la classe de base dans
la hiérarchie de dérivation.
La classe de base partagée est dite classe de base
virtuelle
08/12/2019 INSIM TO 77
L’héritage virtuel
Pour qu'une classe devienne une classe de base virtuelle, il
suffit de faire précéder son nom, dans la liste de dérivation, du
mot clé virtual
Exemple : Implémentation de l'héritage virtuel ci-dessus :
class animal L'ordre des mots clés public
{//...}; et virtual n'est pas important
class aquatique : public virtual animal
{//...};
class terrestre : virtual public animal
{//...};
class amphibien : public aquatique, public
terrestre
{//...};
08/12/2019 INSIM TO 78
Appel des constructeurs dans d'héritage virtuel
08/12/2019 INSIM TO 79
Constructeurs/destructeurs dans d'héritage virtuel
08/12/2019 INSIM TO 80
Fonctions virtuelles pures et classes abstraites
Une fonction virtuelle pure est une fonction virtuelle
dont le prototype (signature) est suivi d'une
affectation à 0 [lippman];
La classe qui déclare ce type de fonctions devient
automatiquement une classe abstraite;
La redéfinition des fonctions virtuelles pures est
obligatoire dans toutes les classes dérivées à partir de
cette classe de base abstraite; Dans le cas contraire,
ces classes dérivées deviennent aussi des classes
abstraites.
08/12/2019 INSIM TO 81
Fonctions virtuelles pures et classes abstraites
08/12/2019 INSIM TO 82
Fonctions virtuelles pures et classes abstraites
08/12/2019 INSIM TO 83
La composition
L'héritage public étudié fournit une implémentation d'une
relation de sous typage : "est un" basée sur le concept
généralisation/spécialisation;
C++ permet l’implémentation de la relation qui exprime la
composition entre objets : "possède un" basée sur le concept
de composant/composé ou d’agrégation;
– Exemple : Un ordinateur est composé d'UC, de mémoire, et de
périphériques;
La composition est implémentée en rendant une classe
membre d'une autre classe [lippman]; Il existe deux formes de
composition d'objets en C++ :
– La composition par valeur
– La composition par référence.
08/12/2019 INSIM TO 84
La composition par valeur
C'est l'implémentation de la relation d'agrégation
Un objet réel de la classe composant est déclaré en
tant que membre de la classe composée;
Exemple :
class UC
{//...};
Objet de la classe UC comme
class ordinateur données membres de la classe
{//... ordinateur
UC unit;
//…
};
08/12/2019 INSIM TO 85
La composition par valeur
08/12/2019 INSIM TO 86
La composition par référence
08/12/2019 INSIM TO 87
Programmation orientée objet
en C++
Chapitre 3 : La programmation générique
Auteur : N. TAMANI
La programmation générique
La généricité est un mécanisme de programmation
qui permet d’implémenter des modules (fonctions ou
classe) indépendamment des types de données.
Le but du chapitre : prendre connaissance des bases
de la programmation génériques
Les modèles (patron ou template) de fonctions
Les modèles de classes.
Présentation de la STL (Standard Template Library).
08/12/2019 INSIM TO 89
Les patrons de fonctions
Un patron de fonctions est un mécanisme qui fournit
une gestion automatique des instances particulières
d'une fonction variant selon le type.
un patron de fonctions est un générateur de fonctions
qui réalisent toutes le même traitement mais sur des
types de données différents.
Le patron de fonctions est une généralisation d’un
traitement; l’instance du patron est une application du
traitement à un type (ou ensemble de types) de
données particulier(s).
08/12/2019 INSIM TO 90
Les patrons de fonctions
Exemple : la fonction max()
– Elle peut s’appliquer de façon identique sur des valeurs
entières, doubles, de type string et même sur des objets de
classe surchargeant l'opérateur de test (généralement
l'opérateur supérieur à >).
– La fonction max() peut se définir comme étant un patron de
fonction.
int max (int a, int b)
{ if (a>b) return a; return b;}
T max (T a, T b)
double max (double a, double b) {
{ if (a>b) return a; return b;}
= if (a>b) return a;
return b;
string max (string a, string b) }
{ if (a>b) return a; return b;}
08/12/2019 INSIM TO 91
Déclaration/définition d'un patron de fonctions
Syntaxe :
template <liste_param_type>
//declaration/definition du patron.
template : mot clé du langage pour introduire un modèle de
classe;
list_param_type : la liste des paramètres du patron de la
forme :
class ident ou typename ident séparées par des virgules, ou
encore type_real ident;
class et typename étant des mots clés du langage qui
introduisent ident comme étant un paramètre de type;
type_real un type simple ou composé prédéfini ou défini par
l'utilisateur qui introduit ident comme un paramètre de valeur
du patron;
08/12/2019 INSIM TO 92
Déclaration/définition d'un patron de fonctions
Exemple : le patron de fonction max() déclaré comme suit :
template <typename T>
T max ( T, T);
– max() est un patron de fonction qui accepte deux arguments de type T
et retourne une valeur de type T;
La définition du patron de fonction max () :
template <typename T>
T max ( T a, T b)
{
if (a > b) return a;
return b;
}
Le programmeur peut paramétrer tous les types, ou un sous
ensemble des types, dans l'interface (type retour + signature)
du patron de fonctions
08/12/2019 INSIM TO 93
Les paramètres d’un patron de fonctions
On peut avoir comme paramètre de patron un paramètre non
type; ce nom correspond alors à une valeur transmise au patron
de la fonction.
• La référence pour tab est
Exemple : obligatoire
template <class T, int size> • size est la taille de tab;
void affiche (T (&tab) [size]);
Un identificateur utilisé pour spécifier un paramètre de patron
garde ce statut tout le long de la déclaration/définition du
patron :
Il cache toute déclaration/définition d'objet, classe, type, fonction, etc.
apparaissant dans les portées englobant la déclaration/définition du
patron de fonction.
Toute déclaration/définition d'objets, ou type à l'intérieur de la
définition d'un patron ne doit pas avoir un nom identique à l'un des
identificateurs utilisés pour spécifier un paramètre de ce patron
08/12/2019 INSIM TO 94
Les paramètres d’un patron de fonctions
Les identificateurs doivent être uniques à l'intérieur
de la liste des paramètres du patron.
Exemple : le code suivant est faux, car T est spécifié
deux fois dans la liste de paramètres :
template <class T, class T>
//suite de la déclaration du patron x
Un identificateur utilisé pour spécifier un paramètre
de patron peut être réutilisé pour spécifier un
paramètre de patron dans d'autres déclarations et/ou
définitions de patrons;
08/12/2019 INSIM TO 95
Les paramètres d’un patron de fonctions
Les noms de paramètres de patron n'ont pas besoin
d'être identiques entre la déclaration et la définition
d’un même patron.
Pas de contrainte de nombres d'apparition d'un nom
de paramètre de patron dans la liste de paramètres de
la fonction;
Un patron de fonctions peut aussi être déclaré inline
ou extern;
le mot clé inline (ou extern) ne se mettra pas avant le mot clé
template mais il sera placé devant le type retour du patron :
Exemple :
template <class T>
inline T min (T, T);
08/12/2019 INSIM TO 96
Instanciation de patron de fonctions
Définition : L'instanciation de patron de classe
est la façon avec laquelle les fonctions
individuelles sont construites en précisant des
types et/ou des valeurs réelles en
remplacement des paramètres du patron source
des fonctions;
L'instanciation est effectuée par le compilateur
de façon implicite lorsqu'on fait appel au
patron à l'aide d'arguments de type réels :
Processus dé déduction d’arguments de patron
08/12/2019 INSIM TO 97
Instanciation de patron de fonctions
Exemple : l'instanciation du patron max () est
effectuée à chaque ligne du code où un appel à max()
est invoqué :
Instancier la fonction :
int a = 10, b = 30; int max (int, int); puis
int m = max (a, b); l'invoquer
08/12/2019 INSIM TO 98
Arguments de patron explicites
Soit l'appel suivant :
long int li;
cout << max (li, 3) << endl; x
Le processus de déduction d'arguments ne pourra pas
instancier une fonction max (long int, int)
Incapacité de trouver la fonction à appeler
spécification d'arguments explicites;
La syntaxe est comme suit :
nom_patron <liste_types_réels> (liste_argument_fonction);
liste_types_réels : liste de types réels séparés par des
virgules; chaque type dans cette liste correspond à un
paramètre de type du patron;
08/12/2019 INSIM TO 99
Arguments de patron explicites
Exemple : Instancier le patron max() avec les
arguments li et 3 :
on doit passer par une fonction de spécification
explicite d'arguments :
max<long int> (li, 3);
Le compilateur instanciera directement la fonction
max(long int, long int); sans passer par la déduction
d'arguments.
Il n'est pas obligatoire de fournir pour chaque
paramètre de type un argument explicite dans la liste
d'arguments explicites;
Les arguments qui peuvent être déduits de façon
implicite ne nécessitent pas d'arguments explicites;
08/12/2019 INSIM TO 100
Arguments de patron explicites
On respectera alors la même règle vue pour les arguments par
défaut pour une fonction :
on ne peut omettre que les arguments les plus à droite.
Il existe une autre situation où l'utilisation d'arguments de
patron explicites est inévitable :
template <class T1, class T2>
T1 fct (T2);
Lors de l'appel de la fonction avec un type donné, la déduction
d'argument n'a pas la possibilité de déduire le type réel à
affecter à T1;
on doit impérativement passer par les arguments de patron
explicite : Instancier la fonction :
fct <int> (3.14); int fct (double); puis l'invoquer
array <int, x> v;
Corriger cette erreur :
x
const int x = 20;
array <int, x> v;
Le compilateur l'adresse d'un objet membre d'espace
de noms ainsi que le résultat de l'expression sizeof()
sont des expressions constantes.