Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

try catch using RAII?

I have a class which has some methods like follows (And more):

    template<class T>
    Logpp& operator<<(T const& obj)
    {
        *p_Stream << obj ;
        return *this ;
    }

    Logpp& operator<<(char const* zString)
    {
        *p_Stream << zString ;
        return *this ;
    }

    Logpp& operator<<(std::ostream& (*manip)(std::ostream&))
    {
        *p_Stream << manip;
        return *this ;
    }

I want to enclose the body of functions in a try catch block of the form:

    Logpp& operator<<(std::ostream& (*manip)(std::ostream&))
    {
        try
        {
            *p_Stream << manip;
            return *this;
        }
        catch(ios_base::failure& e)
        {
            //MyException has a stringstream inside and can use operator<<
            throw MyException("IO failure writing to log file : ") << e.what() << endl;
        }
    }

Q1: Is it advisable to use exceptions like this? (In each function). I am not familiar using exceptions so I am not sure.

Q2: If the answer to Q1 is positive, can I do something like this to remove redundancies?

    Logpp& operator<<(std::ostream& (*manip)(std::ostream&))
    {
        Catch<ios_base::failure> tc();
        try
        {
            *p_Stream << manip;
            return *this;
        }
        //destructor of tc will be written to catch the template exception type and rethrow as a MyException.
    }
like image 367
nakiya Avatar asked Dec 16 '22 17:12

nakiya


1 Answers

Q1: Is it advisable to use exceptions like this? (In each function). I am not familiar using exceptions so I am not sure.

There's no particular problem, but no particular reason either unless you're planning to enrich the exception information, differentiate some ios_base::failure functions from others etc.. You only want to make each function bigger / more complex if it makes something else smaller / simpler.

Q2: If the answer to Q1 is positive, can I do something like this to remove redundancies?

You could potentially use a macro to generate the try/catch blocks for you. If you do what you suggest, then the destructor will be called while an exception is being handled: if you try to throw again then terminate() will be called. Check the C++ Lite FAQ for details: http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.9

like image 176
Tony Delroy Avatar answered Dec 19 '22 07:12

Tony Delroy