Всю свою профессиональную жизнь по мере необходимости пользовался dynamic_cast-ом в C++ и не знал, что dynamic_cast не будет делать приведение к ссылке/указателю на непубличный базовый класс.
Вот пример:
|
#include <iostream> class iface { public: virtual ~iface() = default; virtual void f() = 0; }; class basic_impl { public: virtual ~basic_impl() = default; void impl_f() {} }; class first_derived final : public iface, protected basic_impl { public: void f() override { impl_f(); } }; class second_derived final : public iface, public basic_impl { public: void f() override { impl_f(); } }; void try_dynamic_cast(iface * base) { std::cout << "trying to cast " << typeid(*base).name() << std::flush; if(auto * p = dynamic_cast<basic_impl *>(base); p) std::cout << "... OK" << std::endl; else std::cout << "... FAILURE" << std::endl; } int main() { first_derived f; second_derived s; try_dynamic_cast(&f); try_dynamic_cast(&s); } |
Обращаю внимание, что для first_derived класс basic_impl -- это protected-база.
В результате его запуска получим:
trying to cast 13first_derived... FAILURE
trying to cast 14second_derived... OK
Цынк.
PS. Вот так: век живи, век учись. А помрешь все равно дураком 🙂
1 комментарий:
Что в целом выглядит логично: публичный интерфейс basic_impl должен же стать protected у наследника
Отправить комментарий