class D B::B()
{ {
public : cout << "GRAM ";
D(); B_attribut_1 = 0;
D(int n); }
~D();
private : B::B(int n) : B_attribut_1(n)
int D_attribut_1; {
}; cout << "gram ";
}
D::D()
{ B::~B()
cout << "AM "; {
D_attribut_1 = 0; cout << "pique ";
} }
Page 2 sur 8
am stram GRAM PIQUE et pique ET COLEGRAM.
a) (2 pts) Soit une classe Personne, possédant les attributs Prenom, Nom et DateDeNaissance, ainsi que les
méthodes permettant de lire ces attributs, et un constructeur qui crée un objet Personne à partir de son
prénom, de son nom et de sa date de naissance. L’attribut DateDeNaissance est un objet de la classe Date,
qui possède trois attributs privés de type entier Jour, Mois et Annee. Donnez le code de ces classes et des
méthodes, ainsi que celui de leurs constructeur. Attention ! Vous devez donner l’intégralité du code
permettant à ces lignes de fonctionner :
b) Expliquez brièvement pourquoi il n’a pas été pertinent de définir un constructeur par défaut pour cette
classe.
Un constructeur par défaut créerait une personne qui n’aurait ni prénom, ni nom, ni date
de naissance. Un tel objet n’aurait aucune utilité dans une application courante.
c) (2 pts) Donnez le code de la surdéfinition d’un opérateur <= permettant de comparer deux objets quidam_1
et quidam_2 de la classe Personne, et qui retourne TRUE si quidam_1 est plus jeune ou du même âge que
quidam_2, FALSE sinon.
Soit la classe Stack et ses méthodes suivantes qui implémentent une pile d’entiers grâce à un tableau dynamique.
void Stack::push(int n)
{
if (nelem < dim)
stackPtr[nelem++] = n;
}
Page 4 sur 8
a) Modifier le code de la classe Stack et de ses méthodes, de façon à ce qu’elles définissent une classe
générique implémentant une pile de données de type quelconque T.
void Stack::print()
{
int i;
for (i = 0; i < nelem; i++) cout << stackPtr[i] << " ";
cout << "\n";
}
Donnez le code effectuant la surdéfinition de l’opérateur <<, de façon à ce que l’instruction « cout <<
maPile », où maPile est un objet de type Stack, produise le même résultat que l’instruction
« maPile.print() » .
return out;
}
Question 4 - Héritage
Un attribut ou une méthode d’une classe A déclaré protected peut être accédé par les
objets d’une classe B dérivée de A, ce qui n’est pas le cas des attributs et méthodes
privés de A. À noter que les fonctions amies de A peuvent accéder à tous les attributs
de A, même les attributs privés.
Page 6 sur 8
Question 5 – Allocation dynamique
class MyString
{
public :
MyString(); // constructeur I (par défaut)
MyString(char * c); // constructeur II (à partir d'une chaîne)
MyString(const CMyString & s); // constructeur III (de recopie)
~MyString();
MyString & operator = (const CMyString & s);
int operator == (CMyString & s);
MyString operator + (CMyString & s);
char & operator [] (int n);
void Print();
int GetLength();
private :
int m_length; // longueur de la chaîne
char *m_ptr; // pointeur sur la chaîne
};
La classe MyString possède un attribut char *m_ptr, qui est un pointeur vers un tableau dynamique. Un
constructeur de recopie effectue généralement les allocations mémoire sur le tas requises au moment de la
copie d’un objet. Si l’on veut pouvoir recopier une chaîne MyString, un tel constructeur est nécessaire.
Le constructeur de recopie est appelé toutes les fois où un objet créé antérieurement A doit être recopié dans
un objet nouvellement créé B, c’est-à-dire :
• Lors d’une affectation : B = A .
• Lors du passage d’un objet par valeur à une fonction.
Page 7 sur 8