I'm trying to write a class for handling exceptions. I thought it would be useful to add a << operator to give me an easy way to throw error messages. Bellow is my solution to the problem so far. One thing that is bugging me, is that if I delete the stream in the destructor (as shown in my code) I get a segfault. Bellow is the entire code of my exception handling class. I have no idea what may be deleting the stream before the destructor gets to it.
class prc_exception : public std::exception {
private:
int line_num;
std::ostringstream* msg;
public:
prc_exception(const char* part, const int line) throw()
: exception() {
msg = new std::ostringstream();
*msg << "<parcer:" << part << ":" << line << ">: ";
}
~prc_exception() throw() { delete msg; }
virtual const char* what() const throw() { return msg->str().c_str(); }
virtual const int line() const throw() { return line_num; }
template <class T> prc_exception& operator<<(const T& rhs)
{ *msg << rhs; return (*this); }
};
Also, if anybody can suggest a better way of handling what I want to do, please give me an advise. What I want to have is a something usable like this:
throw prc_exception("code_part",__LINE__) << "More info";
which when caught will have it's what() function return a string like:
<parcer:code_part:36>: More info
Thanks a lot.
Solved: As @polkadotcadaver suggested, adding a Copy constructor and a copy assignment operator fixed the issue. The fixed code functions as intended: #include #include
using namespace std;
class prc_exception : public std::exception {
private:
int line_num;
std::ostringstream msg;
public:
prc_exception(const char* part, const int line) throw()
: exception() {
msg << "<parcer:" << part << ":" << line << ">: ";
}
/** Copy Constructor */
prc_exception (const prc_exception& other)
{
line_num = other.line();
msg << other.what();
}
/** Copy Assignment Operator */
prc_exception& operator= (const prc_exception& other)
{
line_num = other.line();
msg << other.what();
return *this;
}
~prc_exception() throw() { }
virtual const char* what() const throw() { return msg.str().c_str(); }
virtual const int line() const throw() { return line_num; }
template <class T> prc_exception& operator<<(const T& rhs)
{ msg << rhs; return (*this); }
};
int main()
{
try
{
throw prc_exception("hello", 5) << "text." << " more text.";
} catch (exception& e) {
cout << e.what() << endl;
}
return 0;
}