Хочу во время выполнения идентифицировать класс, из которого
брошено исключение. Для этого хочу в параметре конструктора
исключения передавать this, а в самом классе исключения через
RTTI узнать имя класса. this имеет тип type_info, а он закрыт.
Так каким же типом в конструкторе можно объявить указатель на
класс, или как можно корректно преобразовать?
Подскажите кто знает, pls...
Не вполне понял насчёт "this имеет тип type_info, а он закрыт".
Если исключение у вас вызывается в методе класса, который вы хотите идентифицировать, то зачем для этого RTTI, ведь класс и так известен (да ещё и конкретная причина, вызвавшая исключение)? Если же исключение вызывается в связи с использованием указателя/ссылки на объект, тип которого нужно идентифицировать, то можно передать в конструктор исключения ссылку на type_id для этого объекта или сразу имя класса (typeid(*ptr).name(), где ptr - указатель на объект, тип которого нужно узнать). Следует обратить внимание, также, на то, что для корректной работы typeid класс должен быть полиморфным (то есть иметь виртуальные методы).
Если я что-то не так понял, приведите кусок кода с пояснениями, а то трудно понять, в чём проблема.
Действительно, как-то сумбурно написал.
Попробую по порядку.
В своей программе хочу записывать в лог сообщения об ошибках
и имя класса того объекта, в котором выброшено исключение.
Примерно так:int main (int argc, char *argv[]) {
...
try {
SomeClass sc(-1);
}
catch (MyException &e) {
log << e.who() << " -> " << e.what();
throw;
}
...
}Использовать класс MyException хочу так:
class SomeClass {
int _sm;
public:
SomeClass (int sm) {
if (sm >= 0) _sm = sm;
else throw MyException(*this, "sm must be positive");
}
...
};
Класс MyException, предназначенный для обработки специфичных
для моей программы ошибок, примерно таков:class MyException {
? _obj;
string _msg;public:
MyException (? obj, string msg): _obj(obj), _msg(msg) {}
string who () {
string s(typeid(_obj).name());
return s;
}string what () {
return _msg;
}};
Там, где знак вопроса и непонятно.
А по поводу закрытости имел в виду (недоимел :-) конструктор type_info.Непосредственно имена классов передавать пробовал, но возникает
какое-то ощущение недоделанности.
#include <stdio.h>
#include <string>
#include <typeinfo>class SuperError
{
private:
const char* who_;
std::string what_;public:
SuperError(const char* _who, const std::string& _what)
: who_(_who ? _who : "<null>"), what_(_what)
{}
const char* who() const throw() { return who_; }
const char* what() const throw() { return what_.c_str(); }
};template<typename C>
void raiseError(const C& c, const std::string& msg)
{
throw SuperError(typeid(c).name(), msg);
}
class MyClass
{
public:
MyClass()
{
raiseError(*this, "some ugly message");
}
};
int main()
{
try {
MyClass myClass;
} catch(const SuperError& err) {
printf("'%s' -> '%s'\n", err.who(), err.what());
}
return 0;
}