4.0 KiB
4.0 KiB
Семинар 6
RTTI - Run Time Type Identification
- typeid
- dynamic_cast
typeid
typeidвозвращает тип объекта/указателя. Если указатель на класс с виртуальными функциями, вернёт именно тип объекта. Иначе - указателя.
Для type_info переопределённые операции и методы:
- ==
- !-
- .name
class A {
public:
virtual void f() {}
};
class B : public A {};
int main () {
A *pa = new B;
B *pb;
std::cout << typeid(*pa).name; // 1B (1 символ в имени)
if (typeid(*pa) == typeid(B)) {
pb = (B*)pa; // небезопасное приведение
}
}
Dynamic cast
class A {
public:
virtual void f() {}
};
class B : public A {};
int main () {
A *pa, a;
B *pb, b;
pa = &b;
// безопасно приводит, вернёт не NULL в случае успеха
pb = dynamic_cast<B*>(pa);
}
class A {
public:
virtual void f() {}
};
class B : public A {};
int main () {
A *pa, a;
B *pb, b;
A &pr = a;
// B &rb = dynamic_cast<B&>(pa); // выкинет bad_cast
}
Исключения
try - throw - catch
terminate() - в случае, если ничего не обработалось
приводится в catch указатели к константным могут
int f() {
try {
...
throw 10;
...
throw "abc";
...
throw A();
...
} catch (int a) {
...
throw ...; // тогда обработается функцией выше
...
} catch (const char* s) {
...
} catch (A &x) {
...
} catch (...) { // все остальные исключения
}
}
В случае возвращение класса, который наследуется от базового, "ловить" надо сначала производный, после - базовый Деструктор для создаваемого класса вызывается только после фулл обработки исключения (если catch сам вызвал throw)
int f() throw(int, char) {
try {
...
throw 1.2;
...
} catch (double) {
...
}
}
unexpected() - вызывается, если мы на внешнюю функцию передаём исключение типа, который не указан
// никакие не передавать вовне
int f() throw();
after c++17 only:
int f() noexcept;
Алгоритм обработки исключений
- создание временного объекта типа возвращаемого исключения
- уничтожение объектов в
tryблоке - выход из
try - подбор нужного обработчика
- если больше исключений нет - деструктор временного объекта
- если не обработано - выход к внешнему обработчику
5.14. Что напечатает следующая программа?
struct S {
S ( int a) {
try {
if (a > 0) throw *this ;
else if (a < 0) throw 0;
}
catch ( S & ) {
cout << “SCatch_S&” << endl;
} catch (int ) { throw ; }
cout << “SConstr” << endl;
}
S (const S & a) { cout << “Copy” << endl; }
~S ( ) { cout << “Destr” << endl; }
};
int main ( ) {
try {
S s1( 0 ), s2 ( 5 );
cout << “Main” << endl;
}
catch (S &) { cout << “MainCatch_S&” << endl; }
catch ( ... ) { cout << “MainCatch_...” << endl; }
return 0;
}
Результат отработки программы:
Sconstr
Copy
Scatch_s&
Destr
Sconstr
Main
Destr
Destr
1 14 15 CatchB bad_cast 63 63 3 ... End