стирается. • Имея указатель T *ptr, мы не можем проверить, действительно ли по нему лежит объект класса T. • Но: C++ предоставляет такую возможность, как Run-Time Type Information (RTTI).
константный объект типа type_info. #include <iostream>! #include <typeinfo>! ! using namespace std;! ! int main() {! int *a = 0, b = 0;! ! if (typeid(a) != typeid(b)) {! cout << "a and b are of different types:\n";! cout << "a is: " << typeid(a).name() << '\n';! cout << "b is: " << typeid(b).name() << '\n';! }! return 0;! } a and b are of different types:! a is: int *! b is: int
! class Base { virtual void f() {} };! class Derived: public Base {};! ! int main () {! try {! Base *a = new Base;! Base *b = new Derived;! cout << "a is: " << typeid(a).name() << '\n';! cout << "b is: " << typeid(b).name() << '\n';! cout << "*a is: " << typeid(*a).name() << '\n';! cout << "*b is: " << typeid(*b).name() << '\n';! } catch (exception& e) {! cout << "Exception: " << e.what() << endl; ! }! ! return 0;! } a is: class Base *! b is: class Base *! *a is: class Base! *b is: class Derived
(где есть хотя бы одна виртуальная функция, хотя бы виртуальный деструктор). • RTTI тратит дополнительные ресурсы. • Вызов typeid гораздо дешевле, чем dynamic_cast. • Зачастую можно обойтись без RTTI. • RTTI далеко до настоящего Reflection, который есть в других языках.
y ? x : y; }! inline long max(long x, long y) { return x > y ? x : y; }! inline float max(float x, float y) { return x > y ? x : y; }! inline double max(double x, double y) { return x > y ? x : y; }! ! // ......???????! ЯЗЫК C++
int const &min(int const &x, int const &y) {! return x < y ? x : y;! } template <typename T>! inline T const &min(T const &x, T const &y) {! return x < y ? x : y;! } Компилятор в поисках функции min находит шаблон и выводит тип T по типу аргументов функции Инстанцирование шаблона Подстановка инстанцированной функции
его методов для некоторого набора аргументов шаблона. template <typename T>! class Storage8 {! T objects[8];! ! public:! void set(int idx, const T &t) {! objects[idx] = t;! }! ! const T& operator[](int idx) {! return objects[idx];! }! }; Хочется сделать Storage8<bool>, который бы хранил значения в битах для экономии памяти
T. В большом проекте это может привести к разбуханию кода. • С низкоуровневой точки зрения реализации List<int *>::append() и List<void *>::append() идентичны. • Нельзя ли использовать этот факт для оптимизации списков указателей? template <typename T>! class List {! public:! // ....! void append(T const &);! inline size_t length() const;! // ....! };