4

Note: I can't use anything that is default.

I am trying to make a very simple exception handling routine or at the very least make something that looks the part. I don't want to do very much, just throw an exception and print an error message.

in .h

class MyException {
    protected: string message;

    public:

        MyException (string mes) {
            this->message = mes;
        }

        MyException (); // is this necessary ? does it do anything ?

        string getMessage() const {
            return this->message;
        }
};

What I'd want is to have a "PersonException" and "ActivityException". Might use a template but not sure if that would work out.

class PersonException:public MyException {

    public:

        PersonException (string message):MyException(message) {

        }
};


class PersonValidator {

    public:

        PersonValidator (Person p) throw (PersonException);
};

in .cpp

void PersonValidator::PersonValidator(Person p) throw (PersonException) {
    if (p.getPhone < 0) {
        throw PersonException ("Person Number is invalid");
}

What here is wrong or cumbersome, how could it be done better ? and where do I actually print the error message ?

The Unfun Cat
  • 29,987
  • 31
  • 114
  • 156
Kalec
  • 2,681
  • 9
  • 30
  • 49

2 Answers2

10

1) The default constructor is not necessary, at least the way you have the code now, so you can remove

 MyException ();

2) It's recommended to derive exceptions from std::exception.

3) You can catch your exceptions by catching a MyException&, and print the message there :

try
{
    PersonValidator validator(Person());
}
catch(const MyException& ex)
{
    std::cout << ex.getMessage();
}

4) Avoid using directives in headers. Your syntax suggests you have a using namespace std; in the header. That's wrong, you should favor full name qualification, at least in headers:

protected: std::string message;
MyException (std::string mes)

etc.

5) Favor pass by const reference instead of pass by value, for complex types:

MyException (const std::string& mes)

PersonValidator (const Person& p)

6) Aim for const correctness:

std::string getMessage()

should be:

std::string getMessage() const

since it doesn't change any members.

7) Use initialization lists:

 MyException (string mes) {
     this->message = mes;
 }

becomes

 MyException (string mes) : message(mes) {
 }
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • Hmm, why should I not use `using namespace std;` ? – Kalec May 15 '12 at 12:50
  • @Kalec in short, it pollutes the global namespace. – Luchian Grigore May 15 '12 at 12:51
  • 1
    @Kalec tones of discussions about this on SO, not worth repeating. http://stackoverflow.com/questions/6077566/using-namespace-std – Luchian Grigore May 15 '12 at 12:51
  • I think this will be my last question: is it not at all possible (even if unwise) to print the exception message somewhere in the code I provided. I would love to re-write the code for it to be better but I don't have that much time. I'd just like to throw an exception and print that message (without catch). – Kalec May 15 '12 at 13:03
  • @Kalec you can always print it in the constructor. – Luchian Grigore May 15 '12 at 13:04
0

you can also use default constructor to initialize to some pre-defined value.

MyException () : message ("throwing an exception") {};
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • Just edited, sorry. I can't use anything default, it has to be done by me. Even if it's not very good and ends up being very simple. – Kalec May 15 '12 at 12:55