M2103-TP4-Exo-4

Créez le projet RationnelV2.

copiez-y le contenu des fichiers
CstCodErr.h :

/**
 *
 * \file     CstCodErr.h
 *
 * \authors  M. Laporte, D. Mathieu
 *
 * \date     10/02/2011
 *
 * \version  V1.0
 *
 * \brief    Codes d'erreurs
 *
 **/
#ifndef __CSTCODERR_H__
#define __CSTCODERR_H__

namespace nsUtil
{
    enum {KNoExc       = 0,
          KNoError     = 0,

          KExcStd      = 254,
          KExcInconnue = 255 
         };

} // namespace nsUtil

#endif /*  __CSTCODERR_H__  */

CException.h :

/**
 *
 * \file     CException.h
 *
 * \authors  M. Laporte, D. Mathieu
 *
 * \date     10/02/2011
 *
 * \version  V1.0
 *
 * \brief    Declaration de la classe CException
 *
 **/
#ifndef __CEXCEPTION_H__
#define __CEXCEPTION_H__


#include <string>
#include <exception>

#include "CstCodErr.h"

namespace nsUtil
{
    class CException : public std::exception
    {
        std::string myLibelle;
        unsigned    myCodErr;

      public :
        CException (const std::string & libelle = std::string(), 
                    const unsigned      codErr  = KNoExc)     noexcept;
        virtual ~CException (void)                            noexcept;

        const std::string & getLibelle (void) const           noexcept;
        unsigned            getCodErr  (void) const           noexcept;

        virtual const char* what       (void) const           noexcept;

        void display (void) const;

    }; // CException
    
} // namespace nsUtil
#endif /*  __CEXCEPTION_H__  */

CException.cpp :

/**
 *
 * \file     CException.cpp
 *
 * \authors  M. Laporte, D. Mathieu
 *
 * \date     10/02/2011
 *
 * \version  V1.0
 *
 * \brief    classe CException
 *
 **/
#include <string>
#include <iostream>

#include "CstCodErr.h"
#include "CException.h"

using namespace std;

#define CEXC nsUtil::CException

//==========================
// Classe nsUtil::CException
//==========================

CEXC::CException (const string & libelle /* = string () */,
                  const unsigned codErr  /* = KNoExc  */) noexcept 
    : myLibelle (libelle), myCodErr (codErr) {}

const string & CEXC::getLibelle (void) const noexcept 
{
    return myLibelle;

} // GetLibelle()

unsigned CEXC::getCodErr (void) const noexcept { return myCodErr;  }

CEXC::~CException (void) noexcept {}

const char* CEXC::what (void) const noexcept  { return myLibelle.c_str(); }

void CEXC::display (void) const
{ 
    cout << "Exception : " << myLibelle << '\n'
         << "Code      : " << myCodErr  << endl;

} // Afficher()

#undef CEXC

SqueletteMain.cpp :

/**
 *
 * \file   : SqueletteMain.cpp
 *
 * \author : 
 *
 * \date   : 
 *
**/

#include <iostream>
#include <exception>

#include "CstCodErr.h"
#include "CException.h"

using namespace std;
using namespace nsUtil;

namespace
{
    void testDivisionParZero (void)
    {
		//TODO
		
    } // testDivisionParZero ()

} // namespace

int main (void)
{
    try
    {
        testDivisionParZero ();

        return KNoExc;
    }
    catch (const CException & e)
    {
        cerr << "Erreur        : " << e.getLibelle () << '\n' 
             << "Code d'erreur = " << e.getCodErr ()  << '\n';
        return e.getCodErr();
    }    
    catch (const exception & e)
    {
        cerr << "Exception standard : " << e.what () << '\n'; 
        return KExcStd;
    }    
    catch (...)
    {
        cerr << "Exception inconnue\n";
        return KExcInconnue;
    }    

} // main()

Rationnel.h :

/**
 *
 * \file    Rationnel.h
 *
 * \authors M. Laporte, D. Mathieu
 *
 * \date    01/02/2008
 *
 * \version V1.0
 *
 * \brief   Declaration de la classe Rationnel (V1)
 *             Ajout des operateurs de relation
 *
 **/
#ifndef __RATIONNEL_H__
#define __RATIONNEL_H__

namespace nsMath
{
    class Rationnel 
    {
        int myNum;
        int myDenom;
 
        void simplify (void);

      public : 
        Rationnel (const int num = 0, const int denom = 1); 
        Rationnel (const Rationnel & r);

        void display (void) const;

        bool operator <       (const Rationnel & r)  const;
        bool operator ==      (const Rationnel & r)  const;

        Rationnel operator + (const Rationnel & r)  const;
        Rationnel operator - (const Rationnel & r)  const;
        Rationnel operator * (const Rationnel & r)  const;
        Rationnel operator / (const Rationnel & r)  const;

    }; // Rationnel 
    
} // namespace nsMath

#endif /*  __RATIONNEL_H__  */

et Rationnel.cpp :

/**
 *
 * \file    Rationnel.cpp
 *
 * \authors M. Laporte, D. Mathieu
 *
 * \date    07/12/2011
 *
 * \version V1.0
 *
 * \brief   Definition des methodes de la classe Rationnel 
 *             (version 1)
 *
 **/
#include <iostream>
#include <cmath>    // abs()

#include "Rationnel.h"

#define RATIONNEL nsMath::Rationnel

using namespace std;
using namespace nsMath;

namespace
{
/*
    unsigned PGDC (const unsigned a, const unsigned b) 
    {
        if (a == b) return a; 
        if (a < b) return PGDC (a, b - a);
        if (a > b) return PGDC (b, a - b); 

    } // PGDC()
*/
    unsigned PGDC (unsigned a, unsigned b) 
    {
        for ( ; a != b; )
        {
            if (a < b)
                b -= a;
            else
                a -= b;
        }
        return a;

    } // PGDC()

} // namespace

RATIONNEL::Rationnel (const int num   /* = 0 */, 
                      const int denom /* = 1 */) 
    : myNum (num), myDenom (denom)
{
    simplify ();

} // Rationnel()

RATIONNEL::Rationnel (const Rationnel & r) 
    : myNum (r.myNum), myDenom (r.myDenom) {}

void RATIONNEL::display (void) const
{
    cout << myNum << '/' << myDenom;

} // display()

void RATIONNEL::simplify (void) 
{
    if (myDenom < 0)
    {
        myNum   = -myNum;
        myDenom = -myDenom;
    }
    int pgdc = (myNum == 0) ? myDenom 
                            : PGDC (abs (myNum), abs (myDenom));

    myNum   /= pgdc;
    myDenom /= pgdc;

} // simplify() 

bool RATIONNEL::operator < (const Rationnel & r) const 
{
    return myNum * r.myDenom < myDenom * r.myNum;

} // operator <

bool RATIONNEL::operator == (const Rationnel & r) const 
{
    return myNum == r.myNum && myDenom == r.myDenom;

} // operator ==

RATIONNEL RATIONNEL::operator + (const Rationnel & r) 
    const  
{
    return Rationnel (myNum   * r.myDenom + r.myNum * myDenom, 
                      myDenom * r.myDenom); 

} // operator +

RATIONNEL RATIONNEL::operator - (const Rationnel & r) 
    const  
{
    return Rationnel (myNum   * r.myDenom - r.myNum * myDenom, 
                      myDenom * r.myDenom); 

} // operator -

RATIONNEL RATIONNEL::operator * (const Rationnel & r) 
    const  
{
    return Rationnel (myNum   * r.myNum, 
                      myDenom * r.myDenom); 

} // operator *

RATIONNEL RATIONNEL::operator / (const Rationnel & r) 
    const  
{
    return Rationnel (myNum * r.myDenom, myDenom * r.myNum); 

} // operator /

#undef RATIONNEL

Renommer SqueletteMain.cpp en TestCRationnel.cpp.

Modifiez les fonctions membres susceptibles d’effectuer des divisions par zéro en :

  • ajoutant throw (CException) à leur profil,
  • levant une CException de code d’erreur CstExcDivZero accompagné d’un message d’erreur adéquat chaque fois qu’une division par zéro est détectée,

Dans la fonction TestCRationnel() du fichier TestCRationnel.cpp, tester les différents cas d’exceptions.