This repository has been archived on 2026-07-28. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
2025-04-13 21:48:15 +03:00

188 lines
4.0 KiB
Markdown

# Семинар 6
## RTTI - Run Time Type Identification
- typeid
- dynamic_cast
### typeid
> `typeid` возвращает тип объекта/указателя. Если указатель на класс с виртуальными функциями, вернёт именно тип объекта. Иначе - указателя.
Для `type_info` переопределённые операции и методы:
- ==
- !-
- .name
```cpp
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
```cpp
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);
}
```
```cpp
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` указатели к константным могут
```cpp
int f() {
try {
...
throw 10;
...
throw "abc";
...
throw A();
...
} catch (int a) {
...
throw ...; // тогда обработается функцией выше
...
} catch (const char* s) {
...
} catch (A &x) {
...
} catch (...) { // все остальные исключения
}
}
```
В случае возвращение класса, который наследуется от базового, "ловить" надо сначала производный, после - базовый
Деструктор для создаваемого класса вызывается только после фулл обработки исключения (если catch сам вызвал throw)
```cpp
int f() throw(int, char) {
try {
...
throw 1.2;
...
} catch (double) {
...
}
}
```
`unexpected()` - вызывается, если мы на внешнюю функцию передаём исключение типа, который не указан
```cpp
// никакие не передавать вовне
int f() throw();
after c++17 only:
int f() noexcept;
```
### Алгоритм обработки исключений
- создание временного объекта типа возвращаемого исключения
- уничтожение объектов в `try` блоке
- выход из `try`
- подбор нужного обработчика
- если больше исключений нет - деструктор временного объекта
- если не обработано - выход к внешнему обработчику
```cpp
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;
}
```
Результат отработки программы:
```text
Sconstr
Copy
Scatch_s&
Destr
Sconstr
Main
Destr
Destr
```
1
14
15
CatchB
bad_cast
63
63
3
...
End