Step 11 (S-11572)

From Stepik Wiki
Jump to: navigation, search

Step on Stepik: https://stepik.org/lesson/564/step/11

В первом уроке вы реализовали простой шаблон ValueHolder, в этом задании мы используем его чтобы написать класс Any (интересно, что не шаблонный), который позволяет хранить значения любого типа! Например, вы сможете  создать массив объектов типа Any, и сохранять в них int-ы, double-ы или даже объекты Array. Подробности в шаблоне кода.

Hint: в нешаблонном классе Any могут быть шаблонные методы, например, шаблонный конструктор.


Для реализации вам может потребоваться оператор dynamic_cast.

С++ предоставляет и более простой способ узнать конкретный класс по указателю (или ссылке) на базовый класс. Для этого можно использовать оператор dynamic_cast. Например, если у вас есть указатель Expression *, и вы хотите узнать, указывает ли этот указатель на самом деле на объект Number, то сделать это можно так:


Expression *expression = parse(code);Number *number = dynamic_cast<Number *>(expression);if (number)    std::cout << "It's a number" << std::endl;else    std::cout << "It is not a number" << std::endl;

 

Если expression действительно указывает на объект Number (или на один из его наследников, но в нашем примере их нет), то оператор dynamic_cast<Number *> вернет правильный указатель. Если expression указывает не на класс Number, то будет возвращен нулевой указатель. Т. е. если в переменной number хранится нулевой указатель, значит expression не указывает на Number на самом деле.

Для правильной работы оператора dynamic_cast в нашем примере требуется, чтобы класс Expression был полиморфным, т. е. в нем должна быть как минимум одна виртуальная функция (например, деструктор). Стандарт определяет работу dynamic_cast и с не полиморфными типами, но в этом случае никаких проверок типа времени исполнения выполняться не будет - часто, это не то, что требуется.

Если передать оператору dynamic_cast нулевой указатель, то он просто вернет нулевой указатель нужного типа, поэтому проверять указатель перед передачей в dynamic_cast не нужно.