I have a function that does some logical error-checks on a structure I have, basically it will do a series of "if" checks and throw a string if it finds something wrong. This string is not caught, the idea is just to report the error and kill the process. I'd like to do something like this:
1 2 3
if (some_check) {
throw string("check(): Hidden node count of " + N_size_file + " exceeds maximum allowed value of " + _N_MAX);
}
I think you can see what I'm trying to do here. Obviously this doesn't work, but I would like this to basically throw this:
check(): Hidden node count of 5000 exceeds maximum allowed value of 4500
As I am writing dozens of these checks, I was hoping that I'd be able to keep it as short as possible. Performance is not an issue, as these checks are only performed during loading or in debugging situations.
For dynamic parameter like N_size_file which is determined at run-time, you have two options. The C style using sprintf or C++ style using ostringstream.
#include <iostream>
#include <sstream>
#include <exception>
usingnamespace std;
class MyException : public exception {
private:
string* m_ex;
public:
MyException(const string& ex) {
m_ex = new string(ex);
};
MyException(constchar* ex) {
m_ex = new string(ex);
};
MyException(const MyException& e) throw() {
if (e.m_ex) m_ex = new string(*(e.m_ex));
}
MyException& operator=(const MyException& e) throw() {
if (e.m_ex) m_ex = new string(*(e.m_ex));
}
~MyException() throw() {
if (m_ex) delete m_ex;
};
constchar* what() constthrow() {
return m_ex ? m_ex->c_str() : "cannot find exception string";
}
};
int main(int argc,char** argv) {
int N = 10;
try {
#ifdef C_STYLE
char buffer[81];
sprintf(buffer,"C: can see my own exception %d?",N);
throw MyException(buffer);
#else
ostringstream oss;
oss << "C++: can see my own exception " << N << "?";
throw MyException(oss.str());
#endif
} catch(MyException& ex) {
cout << ex.what() << "\n";
}
return 0;
}
PS
1. Change parameter for constructor to const to reflect the intention of the class better.
2. C++ exception base class does not mandate a no-arg constructor so I did not code it. If you want you can add to the MyException class
Hi I welcome all criticism. Going by argument, if heap memory can run out then so can stack memory. So does that mean if we switch to use stack memory we will be safe? Writing a bullet-proof exception class is not easy but I feel my version should suffice for most business needs unless it is very stringent memory environment. For that we should not even use exception class, we should revert back to use our traditional return int values isn't it ?
throw std::runtime_error("check(): Hidden node count of " + std::to_string(N_size_file) + " exceeds maximum allowed value of " + std::to_string(_N_MAX));
std::to_string(...) is there a standard C++ function called to_string ? Hmmm...
throw std::runtime_error("check(): Hidden node count of " + std::to_string(N_size_file) + " exceeds maximum allowed value of " + std::to_string(_N_MAX));
why do you unnecessary complicate your class by using dynamic allocation?
Well it could be using stack also. Possibly since long time no touch C++ (busy with Android), I want to refresh my understanding of dynamic allocation :P
In a way, the example goes to show C++ is flexible to accommodate various mode unlike Java where all objects are stored by reference so as to speak.
If you like, you can just change the class to using stack variable also. It shouldn't be so hard, in fact it will be easier.