/**
*
* \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,
KExcDivZero = 11, // Division par zero
KExcArg = 253,
KExcStd = 254,
KExcInconnue = 255
};
} // namespace nsUtil
#endif /* __CSTCODERR_H__ */
/**
*
* @file IEditable.hpp
*
* @authors D. Mathieu, M. Laporte
*
* @date 17/03/2010
*
* @version V2.0
*
**/
#ifndef __IEDITABLE_HPP__
#define __IEDITABLE_HPP__
#include <iostream>
namespace nsUtil
{
class IEditable;
/* */
std::ostream & operator << (std::ostream & os,
const IEditable & obj);
/* */
class IEditable
{
protected :
virtual std::ostream & display (std::ostream & os) const = 0;
public :
virtual ~IEditable (void) {}
friend std::ostream & operator << (std::ostream & os,
const IEditable & obj);
}; // IEditable
} // nsUtil
// inline pour remplacer chaque appel par le corps de la fonction
// et donc éviter que ce soit une définition qui entrainerait des risuqes de multiples
// définitions à l'édition de liens.
inline
std::ostream & nsUtil::operator << (std::ostream & os,
const IEditable & obj)
{
return obj.display (os);
} // operator <<
#endif /* __IEDITABLE_HPP__ */
/**
*
* @file ClasseEditable.cpp
*
* @authors D. Mathieu
*
* @date 24/03/2011
*
* @version V2.0
*
* @brief Test de la classe IEditable
*
**/
#include <iostream>
#include "IEditable.hpp"
#include "CstCodErr.h"
using namespace std;
using namespace nsUtil; // IEditable
namespace
{
void contenu (const IEditable & ed) { cout << ed << endl; }
class CA : public IEditable
{
virtual ostream & display (ostream & os) const
{
return os << "Objet de la classe CA\n";
} // display()
public :
virtual ~CA (void) {}
}; // CA
class CB : public IEditable
{
virtual ostream & display (ostream & os) const
{
return os << "Objet de la classe CB\n";
} // display()
public :
virtual ~CB (void) {}
}; // CB
void classeEditable (void)
{
CA A;
CB B;
contenu (A);
contenu (B);
}// classeEditable ()
} // namespace
int main (int argc, char * argv [])
{
if (argc != 1)
{
cerr << "Nombre d'arguments invalide\n"
"Usage : ./ClasseEditable\n";
return KExcArg;
}
classeEditable();
return 0;
} // main()
Archives du 4 juin 2018
M2103-TP6-Exo-2-Corrigé
/**
*
* @file CException.h
*
* @authors M. Laporte, D. Mathieu
*
* @date 23/03/2010
*
* @version V1.0
*
* @brief classe CException
*
**/
#ifndef __CEXCEPTION_H__
#define __CEXCEPTION_H__
#include <string>
#include <iostream>
#include <exception>
#include "CstCodErr.h"
#include "CEditable.h"
namespace nsUtil
{
class CException : public std::exception, public IEditable
{
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;
protected :
virtual std::ostream & display (std::ostream & os) const;
}; // CException
} // namespace nsUtil
#endif /* __CEXCEPTION_H__ */
/**
*
* @file CException.cpp
*
* @authors M. Laporte, D. Mathieu
*
* @date 02/04/2010
*
* @version V1.0
*
* @brief classe CException
*
**/
#include <string>
#include <iostream>
#include "CstCodErr.h"
#include "IEditable.hpp"
#include "CException.h"
using namespace std;
ostream & nsUtil::CException::display (ostream & os) const
{
return os << "Exception : " << myLibelle << '\n'
<< "Code : " << myCodErr;
} // display()
#define CEXC nsUtil::CException
CEXC::CException (const std::string & libelle /* = std::string () */,
const unsigned codErr /* = KNoExc */)
noexcept
: myLibelle (libelle), myCodErr (codErr) {}
const std::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() const noexcept { return myLibelle.c_str(); }
#undef CEXC
/**
*
* @file TestCException.cpp
*
* @authors D. Mathieu
*
* @date 17/03/2010
*
* @version V2.0
*
* @brief Test de la classe CException
*
**/
#include <iostream>
#include <string>
#include <esception>
#include "CException.hpp"
#include "CstCodErr.h"
using namespace std;
using namespace nsUtil; // CException
namespace
{
class ExcFille : public CException
{
public :
ExcFille (const string & libel, unsigned val) throw ()
: CException (libel, val) {}
protected :
virtual ostream & display (ostream & os) const
{
return CException::display (os) << " de la classe fille";
} // display()
}; // CFille
void testCException (void)
{
throw ExcFille ("Test du polymorphisme", 25);
}// testCException ()
} // namespace
int main (int argc, char * argv [])
{
if (argc != 1)
{
cerr << "Nombre d'arguments invalide\n"
"Usage : ./TestCException\n";
return KExcArg;
}
try
{
testCException();
return KNoExc;
}
catch (const CException & e)
{
cerr << e << '\n';
return e.getCodErr();
}
catch (const exception & e)
{
cerr << "Exception standard : " << e.what() << '\n';
return KExcStd;
}
catch (...)
{
cerr << "Exception inconnue\n";
return KExcInconnue;
}
} // main()
M2103-TP6-Exo-3-Corrigé
/**
*
* @file Duree.h
*
* @authors M. Laporte, d. Mathieu
*
* @date 07/03/2008
*
* @version V1.0
*
* @brief Declarations de la classe duree
*
**/
#ifndef __DUREE_H__
#define __DUREE_H__
typedef unsigned long long ULLong_t;
#include "IEditable.hpp"
#include "CException.hpp"
namespace nsUtil
{
class Duree
{
private :
ULLong_t myDuree;
short unsigned mySecondes;
short unsigned myMinutes;
short unsigned myHeures;
ULLong_t myJours;
void normaliser (void) noexcept;
public :
explicit Duree (const ULLong_t duree = ULLong_t (0)) noexcept;
ULLong_t getDuree (void) const noexcept;
void setDuree (const ULLong_t duree = ULLong_t (0)) noexcept;
Duree & operator ++ (void) noexcept;
Duree operator ++ (int) noexcept;
Duree & operator -- (void) throw (CException);
Duree operator -- (int) throw (CException);
Duree operator + (ULLong_t duree) const noexcept;
Duree operator - (ULLong_t duree) const throw (CException);
Duree & operator += (ULLong_t d) noexcept;
Duree & operator -= (ULLong_t d) throw (CException);
Duree operator + (const Duree & d) const noexcept;
Duree operator - (const Duree & d) const throw (CException);
Duree & operator += (const Duree & d) noexcept;
Duree & operator -= (const Duree & d) throw (CException);
// Operateurs de comparaison et d'identite
bool operator < (const Duree & d) const noexcept;
bool operator == (const Duree & d) const noexcept;
}; // Duree
} // namespace nsUtil
#endif /* __DUREE_H__ */
/**
*
* @file Duree.cpp
*
* @authors M. Laporte, d. Mathieu
*
* @date 17/03/2010
*
* @version V1.0
*
* @brief Definition des methodes de la classe Duree
*
**/
#include "CException.hpp"
#include "Duree.h"
#include "CstCodErr.h"
#define CDUREE nsUtil::Duree
using namespace std;
using namespace nsUtil;
CDUREE::Duree (const ULLong_t duree /* = UULong_t (0) */) noexcept
: myDuree (duree) { normaliser (); }
ULLong_t CDUREE::getDuree (void) const noexcept { return myDuree; }
void CDUREE::setDuree (ULLong_t duree) noexcept
{
myDuree = duree;
normaliser ();
} // setDuree()
void CDUREE::normaliser (void) noexcept
{
mySecondes = myDuree % 60;
myMinutes = myDuree / 60 % 60;
myHeures = myDuree / 3600 % 24;
myJours = myDuree / 86400;
} // normaliser()
CDUREE CDUREE::operator - (ULLong_t d) const throw (CException)
{
if (myDuree < d)
throw CException ("- : operation interdite",
KExcOpInterdite);
return Duree (myDuree - d);
} // operator -
CDUREE::Duree CDUREE::operator + (ULLong_t d) const noexcept
{
return Duree (myDuree + d);
} // operator +
CDUREE CDUREE::operator - (const Duree & d) const throw (CException)
{
if (myDuree < d.myDuree)
throw CException ("- : operation interdite",
KExcOpInterdite);
return Duree (myDuree - d.myDuree);
} // operator -
CDUREE::Duree CDUREE::operator + (const Duree & d) const noexcept
{
return Duree (myDuree + d.myDuree);
} // operator +
CDUREE & CDUREE::operator ++ (void) noexcept
{
++myDuree;
normaliser ();
return *this;
} // operator ++ pre
CDUREE CDUREE::operator ++ (int) noexcept
{
return Duree (myDuree++);
} // operator ++ post
CDUREE & CDUREE::operator -- (void) throw (CException)
{
if (myDuree == 0)
throw CException ("-- : operation interdite",
KExcOpInterdite);
--myDuree;
normaliser ();
return *this;
} // operator -- pre
CDUREE CDUREE::operator -- (int) throw (CException)
{
if (myDuree == 0)
throw CException ("-- : operation interdite",
KExcOpInterdite);
return Duree (myDuree--);
} // operator -- post
CDUREE & CDUREE::operator += (ULLong_t d) noexcept
{
myDuree += d;
normaliser ();
return *this;
} // operator +=
CDUREE & CDUREE::operator -= (ULLong_t d) throw (CException)
{
if (myDuree < d)
throw CException ("-= : operation interdite",
KExcOpInterdite);
myDuree -= d;
normaliser ();
return *this;
} // operator -=
CDUREE & CDUREE::operator += (const Duree & d) noexcept
{
myDuree += d.myDuree;
normaliser ();
return *this;
} // operator +=
CDUREE & CDUREE::operator -= (const Duree & d) throw (CException)
{
if (myDuree < d.myDuree)
throw CException ("-= : operation interdite",
KExcOpInterdite);
myDuree -= d.myDuree;
normaliser ();
return *this;
} // operator -=
// Les valeurs par defaut sont rappelees en commentaires car
// interdites
bool CDUREE::operator < (const Duree & d) const noexcept
{
return (myDuree < d.myDuree);
} // operator <
bool CDUREE::operator == (const Duree & d) const noexcept
{
return (myDuree == d.myDuree);
} // operator ==
#undef CDUREE
/**
*
* @file testDuree.cpp
*
* @authors M. Laporte, D. Mathieu
*
* @date 07/12/2011
*
* @version V1.0
*
* @brief test de la classe Duree complete
*
**/
#include <iostream>
#include <exception>
#include <iomanip> // boolalpha
#include "CException.hpp"
#include "CstCodErr.h"
#include "Duree.hpp"
#include "IEditable.hpp"
using namespace std;
using namespace rel_ops;
using namespace nsUtil; // CException
#define classdef typedef
namespace
{
namespace
{
class DureeEditable : public Duree, public IEditable
{
protected :
virtual std::ostream & display (std::ostream & os) const;
public :
explicit DureeEditable (const ULLong_t duree = ULLong_t (0))
noexcept;
// constructeur nécessaire pour utiliser les opérateurs
// qui renvoient
// des Duree (un DureeEditable est un Duree, mais pas
// l'inverse)
DureeEditable (const Duree & duree) noexcept;
virtual ~DureeEditable (void) noexcept;
/* */
DureeEditable & operator ++ (void) noexcept;
DureeEditable & operator -- (void) throw (CException);
DureeEditable operator ++ (int) noexcept;
DureeEditable operator -- (int) throw (CException);
DureeEditable & operator += (ULLong_t d) noexcept;
DureeEditable & operator -= (ULLong_t d) throw (CException);
DureeEditable & operator += (const DureeEditable & d) noexcept;
DureeEditable & operator -= (const DureeEditable & d) throw (CException);
/* */
}; // DureeEditable
DureeEditable::DureeEditable (const ULLong_t duree
/* = ULLong_t (0) */) noexcept
: Duree (duree) {}
DureeEditable::DureeEditable (const Duree & duree) noexcept
: Duree (duree) {}
DureeEditable::~DureeEditable (void) noexcept {}
ostream & DureeEditable::display (ostream & os) const
{
return
os << '[' << setfill (' ')
<< setw (6) << myJours << ':' << setfill ('0')
<< setw (2) << myHeures << ':'
<< setw (2) << myMinutes << ':'
<< setw (2) << mySecondes << ']' << setfill (' ');
} // display()
/* */
DureeEditable & DureeEditable::operator ++ (void) noexcept
{
return *this = Duree::operator ++ ();
} // operator ++()
DureeEditable & DureeEditable::operator -- (void) throw (CException)
{
return *this = Duree::operator -- ();
} // operator --()
DureeEditable DureeEditable::operator ++ (int) noexcept
{
return *this = Duree::operator ++ (0);
} // operator ++()
DureeEditable DureeEditable::operator -- (int) throw (CException)
{
return *this = Duree::operator -- (0);
} // operator --()
DureeEditable & DureeEditable::operator += (ULLong_t d) noexcept
{
return *this = Duree::operator += (d);
} // operator +=()
DureeEditable & DureeEditable::operator -= (ULLong_t d) throw (CException)
{
return *this = Duree::operator -= (d);
} // operator -=()
DureeEditable & DureeEditable::operator += (const DureeEditable & d) noexcept
{
return *this = Duree::operator += (d);
} // operator +=()
DureeEditable & DureeEditable::operator -= (const DureeEditable & d) throw (CException)
{
return *this = Duree::operator -= (d);
} // operator -=()
void testDuree_01 (void)
{
DureeEditable d1 (3661);
DureeEditable d2 (2661);
DureeEditable d3 (3661);
cout << boolalpha;
cout << d1 << " < " << d2 << " : " << (d1 < d2) << '\n';
cout << d2 << " < " << d1 << " : " << (d2 < d1) << "\n\n";
cout << d1 << " > " << d2 << " : " << (d1 > d2) << '\n';
cout << d2 << " > " << d1 << " : " << (d2 > d1) << "\n\n";
cout << d1 << " <= " << d2 << " : " << (d1 <= d2) << '\n';
cout << d2 << " <= " << d1 << " : " << (d2 <= d1) << "\n\n";
cout << d1 << " >= " << d2 << " : " << (d1 >= d2) << '\n';
cout << d2 << " >= " << d1 << " : " << (d2 >= d1) << "\n\n";
cout << d1 << " == " << d2 << " : " << (d1 == d2) << '\n';
cout << d2 << " == " << d1 << " : " << (d2 == d1) << "\n\n";
cout << d1 << " == " << d3 << " : " << (d1 == d3) << "\n\n";
cout << d1 << " != " << d2 << " : " << (d1 != d2) << '\n';
cout << d1 << " != " << d3 << " : " << (d1 != d3) << "\n\n";
cout << noboolalpha;
} // testDuree_01()
void testDuree_02 (void)
{
DureeEditable d1 (3661);
cout << "d1 = " << d1 << '\n';
cout << "d1-- = " << d1-- << '\n';
cout << "d1-- = " << d1-- << '\n';
cout << "--d1 = " << --d1 << '\n';
cout << "--d1 = " << --d1 << "\n\n";
cout << "d1 = " << d1 << '\n';
cout << "d1++ = " << d1++ << '\n';
cout << "d1++ = " << d1++ << '\n';
cout << "++d1 = " << ++d1 << '\n';
cout << "++d1 = " << ++d1 << "\n\n";
cout << "d1 = " << d1 << '\n';
cout << "d1 -= 3 " << (d1 -= 3) << '\n';
cout << "d1 += 3 " << (d1 += 3) << "\n\n";
cout << "d1 += Duree (3) " << (d1 += Duree (3)) << "\n\n";
d1.setDuree (0);
cout << "d1 = " << d1 << '\n';
} // testDuree_03()
void testDuree_03 (void)
{
DureeEditable d1;
try { d1--; }
catch (const CException & e)
{
cout << "d1-- :\n" << e << '\n';
}
try { --d1; }
catch (const CException & e)
{
cout << "--d1 :\n" << e << '\n';
}
try { d1 -= 1; }
catch (const CException & e)
{
cout << "d1 -= 1 :\n" << e << '\n';
}
try { d1 -= Duree (3); }
catch (const CException & e)
{
cout << "d1 -= Duree (3):\n" << e << '\n';
}
} // testDuree_03()
} // namespace
int main (int argc, char * argv [])
{
if (argc != 1)
{
cerr << "Nombre d'arguments invalide\n"
"Usage : testDuree\n";
return CstErrArg;
}
try
{
/* */
cout << "\ntest 1\n";
testDuree_01 ();
/* */
/* */
cout << "\n\ntest 2\n";
testDuree_02 ();
/* */
/* */
cout << "\n\ntest 3\n";
testDuree_03 ();
/* */
return CstNoExc;
}
catch (const CException & e)
{
cerr << e << '\n';
return e.getCodErr();
}
catch (const exception & e)
{
cerr << "Exception standard : " << e.what() << '\n';
return CstExcStd;
}
catch (...)
{
cerr << "Exception inconnue\n";
return CstExcInconnue;
}
} // main()
M2103-TP4-Exo-1-Corrigé
namespace
{
void clearScreen (void)
{
cout << "\033[2J\033[1;1H" << flush;
} // clearScreen()
char choixDansMenu (void)
{
clearScreen();
cout << "A : exception 'exception'\n"
"B : exception standard specifique\n"
"C : exception 'CException'\n"
"D : exception inconnue\n\n"
"Votre choix (suivi de ) : ";
char choix;
cin >> choix;
clearScreen();
return choix;
} // ChoixDansMenu()
void traiterCommande (char cmd)
{
switch (cmd)
{
case 'A' :
case 'a' :
throw exception ();
case 'B' :
case 'b' :
{
// throw runtime_error ("erreur d'execution ...");
string s;
cout << s.at (0);
break; // inutile puisqu'une exception est levee avant
}
case 'C' :
case 'c' :
throw CException ("Surprise, surprise !", 123);
case 'D' :
case 'd' :
throw 123;
}
} // traiterCommande()
void testExceptionsInMain ()
{
for ( ; ; ) traiterCommande (choixDansMenu());
} // testExceptionsInMain()
} // namespace
int main ()
{
try
{
testExceptionsInMain ();
return KNoExc;
}
catch (const CException & e)
{
cerr << "Erreur : " << e.getLibelle () << '\n'
<< "Code d'erreur = " << e.getCodErr () << '\n';
return e.getCodErr();
}
catch (const out_of_range & e) // levee par string::at()
{
cerr << "Exception out_of_range : " << e.what () << '\n';
return KExcStd;
}
*/
/*
catch (const runtime_error & e)
{
cerr << "Exception runtime_error : " << e.what () << '\n';
return KExcStd;
}
*/
catch (const exception & e)
{
cerr << "Exception standard : " << e.what () << '\n';
return KExcStd;
}
/*
catch (const unsigned & e)
{
cerr << "Exception unsigned : " << e << '\n';
return KExcStd;
}
catch (const int & e)
{
cerr << "Exception int : " << e << '\n';
return KExcStd;
}
*/
catch (...)
{
cerr << "Exception inconnue\n";
return KExcInconnue;
}
} // main()
M2103-TP4-Exo-2-Corrigé
/**
*
* \file TestFailure.cpp
*
* \author D. Mathieu, M. Laporte
*
* \date 10/02/2011
*
**/
#include <iostream>
#include "CstCodErr.h"
#include "CException.h"
using namespace std;
using namespace nsUtil;
namespace
{
void testFailure (void)
{
cout << "testFailure\n\n";
cin.exceptions (ios_base::failbit | ios_base::eofbit);
try
{
int i;
for (;;)
{
cout << "Un entier : ";
cin >> i;
}
}
catch (const ios_base::failure & exc)
{
if (cin.eof ()) cerr << "Fin de fichier\n";
else if (cin.fail ()) cerr << "Erreur de lecture\n";
cerr << exc.what () << '\n';
throw;
}
} // testFailure()
} // namespace
int main (void)
{
try
{
testFailure ();
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()
M2103-TP4-Exo-3-Corrigé
/**
*
* \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,
KExcDivZero = 11, // Division par zero
KExcStd = 254,
KExcInconnue = 255
};
} // namespace nsUtil
#endif /* __CSTCODERR_H__ */
/**
*
* \file DivisionParZero.cxx
*
* \author D. Mathieu
*
* \date 07/12/2011
*
**/
#include <iostream>
#include <exception>
#include <iomanip> // setw()
#include "CstCodErr.h"
#include "CException.h"
using namespace std;
using namespace nsUtil;
namespace
{
int divisionEntiere (int num, int denom) throw (CException)
{
if (0 == denom)
throw CException ("Division par zero", KExcDivZero);
return num / denom;
} // divisionEntiere()
void divisionParZero ()
{
int lesNums [] = { 12, 3, -5, 0, 40 };
const unsigned KSzFractions =
sizeof (lesNums) / sizeof (lesNums [0]);
int lesDenoms [KSzFractions] = { 4, 0, -5, 10, 4 };
for (unsigned i = 0; i < KSzFractions; ++i)
{
cout << setw (4) << lesNums [i] << " / "
<< setw (4) << lesDenoms [i] << " = ";
try
{
cout << divisionEntiere (lesNums [i], lesDenoms [i])
<< '\n';
}
catch (const CException & e)
{
cout << "Erreur : " << e.getLibelle()
<< "; Code d'erreur = " << e.getCodErr() << '\n';
}
}
} // divisionParZero()
} // namespace
int main ()
{
try
{
divisionParZero();
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()
M2103-TP4-Exo-4-Corrigé
/**
*
* \file Rationnel.h
*
* \authors M. Laporte, D. Mathieu
*
* \date 06/11/2007
*
* \version V1.0
*
* \brief Declaration de la classe Rationnel - V2
* Gestion des exceptions
*
**/
#ifndef __RATIONNEL_H__
#define __RATIONNEL_H__
#include "CException.h"
typedef unsigned long long ULLong_t;
namespace nsMath
{
class Rationnel
{
int myNum;
int myDenom;
void Simplifier (void) noexcept;
public :
Rationnel (const int num = 0, const int denom = 1)
throw (nsUtil::CException);
Rationnel (const Rationnel & r) noexcept;
void display (void) const;
bool operator < (const Rationnel & r) const noexcept;
bool operator == (const Rationnel & r) const noexcept;
Rationnel operator + (const Rationnel & r) const noexcept;
Rationnel operator - (const Rationnel & r) const noexcept;
Rationnel operator * (const Rationnel & r) const noexcept;
Rationnel operator / (const Rationnel & r) const
throw (nsUtil::CException);
}; // Rationnel
} // namespace nsMath
#endif /* __RATIONNEL_H__ */
/**
*
* \file Rationnel.cpp
*
* \authors M. Laporte, D. Mathieu
*
* \date 07/12/2011
*
* \version V1.0
*
* \brief Definition des methodes de la classe Rationnel (V2)
* Gestion des exceptions
*
**/
#include <iostream>
#include <exception>
#include <cmath> // abs()
#include "Rationnel.h"
#include "CstCodErr.h"
#include "CException.h"
#define RATIONNEL nsMath::Rationnel
using namespace std;
using namespace nsUtil;
using namespace nsMath;
namespace
{
unsigned PGDC (unsigned a, unsigned b) noexcept
{
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 */) throw (CException)
: myNum (num), myDenom (denom)
{
if (myDenom == 0) throw CException ("Diviseur nul", KExcDivZero);
Simplifier ();
} // Rationnel()
RATIONNEL::Rationnel (const Rationnel & r) noexcept
: myNum (r.myNum), myDenom (r.myDenom) {}
void RATIONNEL::display (void) const
{
cout << myNum << '/' << myDenom;
} // display()
void RATIONNEL::Simplifier (void) noexcept
{
if (myDenom < 0)
{
myNum = -myNum;
myDenom = -myDenom;
}
int pgdc = (myNum == 0) ? myDenom
: PGDC (abs (myNum), abs (myDenom));
myNum /= pgdc;
myDenom /= pgdc;
} // Simplifier()
bool RATIONNEL::operator < (const Rationnel & r) const noexcept
{
return myNum * r.myDenom < myDenom * r.myNum;
} // operator <
bool RATIONNEL::operator == (const Rationnel & r) const noexcept
{
return myNum == r.myNum && myDenom == r.myDenom;
} // operator ==
RATIONNEL RATIONNEL::operator + (const Rationnel & r)
const noexcept
{
return Rationnel (myNum * r.myDenom + r.myNum * myDenom,
myDenom * r.myDenom);
} // operator +
RATIONNEL RATIONNEL::operator - (const Rationnel & r)
const noexcept
{
return Rationnel (myNum * r.myDenom - r.myNum * myDenom,
myDenom * r.myDenom);
} // operator -
RATIONNEL RATIONNEL::operator * (const Rationnel & r)
const noexcept
{
return Rationnel (myNum * r.myNum,
myDenom * r.myDenom);
} // operator *
RATIONNEL RATIONNEL::operator / (const Rationnel & r)
const throw (CException)
{
if (r.myNum == 0)
throw CException ("Division par zero", KExcDivZero);
return Rationnel (myNum * r.myDenom, myDenom * r.myNum);
} // operator /
#undef CRATIONNEL
/**
*
* \file TestRationnel.cxx
*
* \authors M. Laporte, D. Mathieu
*
* \date 07/12/2011
*
* \version V1.0
*
* \brief Test de la classe Rationnel (V2)
* Gestion des exceptions
*
**/
#include <iostream>
#include <exception>
#include "Rationnel.h"
using namespace std;
using namespace nsUtil;
using namespace nsMath;
namespace
{
void testRationnel (void)
{
try
{
cout << "Rationnel R1 (12, 0)\n";
Rationnel r1 (12, 0);
cout << "R1 = ";
r1.display ();
cout << '\n';
}
catch (const CException & e)
{
cout << "Erreur : " << e.getLibelle ()
<< "; code d'erreur = " << e.getCodErr () << '\n';
}
try
{
Rationnel r1 (4, 12);
cout << "R1 = ";
r1.display ();
cout << '\n';
Rationnel r2 (0, 12);
cout << "R2 = ";
r2.display ();
cout << '\n';
r1.display();
cout << " / ";
r2.display();
cout << " = ";
(r1 / r2).display ();
cout << '\n';
}
catch (const CException & e)
{
cout << "Erreur : " << e.getLibelle ()
<< "; code d'erreur = " << e.getCodErr () << '\n';
}
} // testRationnel()
} // namespace
int main (void)
{
try
{
testRationnel ();
}
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;
}
return KNoExc;
} // main()