init commit
This commit is contained in:
+187
@@ -0,0 +1,187 @@
|
||||
# Семинар 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
|
||||
Reference in New Issue
Block a user