M2103-TP3-Exo-2

La classe standard string est une classe très riche et indispensable et il est heureux qu’elle existe !

Cependant, on peut lui reprocher l’absence de certaines fonctionnalités, que l’on aimerait bien y trouver.

On se souvient, par exemple, de la mise en majuscules ou en minuscules.

Une première solution est d’écrire des “moulinettes”, fonctions prenant comme paramètre donnée (ou donnée-résultat) la string et la rendant transformée.

C’est ce que nous avons fait précédemment (au premier semestre).

La seconde solution consiste à dériver la classe standard string en une classe CString à laquelle ne sont ajoutées aucun attribut (aucune donnée membre), mais seulement des méthodes (fonctions-membres).

Les seules fonctions qui ne sont pas héritées de la classe mère sont ses constructeurs, son destructeur, ainsi que l’affectation.

En revanche, un constructeur par recopie, un constructeur par défaut, un destructeur et une affectation sont données à la nouvelle classe (comme à chaque nouvelle classe), par le compilateur.

En ce qui concerne le constructeur par recopie, l’affectation et le destructeur, ils ne sont pas notre problème pour le moment.

Leur récriture sera abordée en temps utile.

La classe string possède de nombreux constructeurs ayant chacun leur utilité.

Ne posséder qu’un seul constructeur CString() qui se contente d’appeler le constructeur de sa classe mère, string(), qui lui-même crée une chaîne vide, est un peu frustrant.

C’est pourquoi on dotera la classe CString des mêmes constructeurs que sa classe mère.

Créez le projet CString.

Copier / coller le code suivant :

/**
 *
 * \file     TestCString.cpp
 *
 * \authors  M. Laporte, D. Mathieu
 *
 * \date     05/11/2007
 *
 * \version  V1.0
 *
 * \brief    Test de la classe String, extension de String
 *
 **/

#include <iostream>

#include "CString.h"

using namespace std;
using namespace nsUtil;

namespace
{
    void testString (void)
    {
        cout << "Test des constructeurs\n\n";

        CString s1;
        cout << '"' << s1 << "\"\n";
        cout << s1.append ("s1") << '\n';
        CString s2 ("Coucou");
        cout << (s2 + ' ' + s1) << '\n';
        CString s3 ("Coucou", 4);
        cout << s3 << '\n';
        CString s4 (10, '#');
        cout << s4 << '\n';

        CString s5 ("AbCdEf1234");
        cout << s5 << '\n';
        cout << s5.toupper() << '\n';
        cout << s5 << '\n';
        cout << s5.tolower() << '\n';
        cout << s5 << '\n';

        cout << "\nTest des fonctions\n\n";
        CString STR ("MAJUSCULE");
        CString str ("minuscule");
        CString space ("  \t\t\n\n");

        cout << boolalpha;

        cout << str   << " alpha ? "  << str.isalpha   () << '\n';
        cout << str   << " alnum ? "  << str.isalnum   () << '\n';
        cout << str   << " digit ?  " << str.isdigit   () << '\n';
        cout << str   << " xdigit ? " << str.isxdigit  () << '\n';
        cout << str   << " lower ? "  << str.islower   () << '\n';
        cout << str   << " upper ? "  << str.isupper   () << '\n';
        cout << str   << " space ? "  << str.isspace   () << '\n';
        cout << STR   << " upper ? "  << STR.isupper   () << '\n';
        cout << str   << " lower ? "  << str.islower   () << '\n';
        cout << space << " space ? "  << space.isspace () << '\n';

        cout << noboolalpha;

    } // testString ()

} // namespace

int main (void)
{
    testString();

    return 0;

} // main()

Dans l’espace de noms nsUtil des fichiers CString.h et CString.cpp, dériver publiquement la classe string (afin de garder et de transmettre la visibilité sur les fonctions membres de la classe mère).

Lui ajouter les constructeurs ayant les mêmes profils que les constructeurs suivants de la classe string, et qui se contentent d’appeler ces derniers en leur passant les mêmes paramètres :

string (const char * NTCTS); 
string (const char * NTCTS, size_type size);
string (const string & S, size_type pos = 0, size_type size = npos);
string (size_type size, char c);

Ajouter les fonctions membres tolower() et toupper(), de même identificateurs que les fonctions standard tolower() et toupper() qui s’appliquent aux caractères.

Le paramètre désignant la chaîne à traiter n’a plus lieu d’être puisque les fonctions deviennent des méthodes de la classe CString (fonctions-membres), donc appelées sur un objet donné.

Rappel : l’objet lui-même est désigné par (*this).

Ajoutez les prédicats isalpha(), isdigit(), isalnum(), isxdigit(), islower(), isupper(), isspace(), extensions des mêmes fonctions standard existant pour les caractères.

Si vous les avez faites, ajoutez aussi les fonctions complémentaires qui vous avaient été proposées : leftAlign(), compact(), rightAlign(), expandTab(), justify().