向下转型 unique_ptr
在面向对象编程领域,继承在促进代码重用和可扩展性方面发挥着关键作用。然而,可能会出现需要“向下转换”unique_ptr
为了解决这一挑战,请考虑一个假设场景,其中应用程序使用多个工厂,每个工厂生成 unique_ptr
unique_ptr<Base> DerivedAFactory() { return unique_ptr<Base>(new DerivedA); }
目标是将返回的 unique_ptr
unique_ptr<Derived> ptr = static_cast<unique_ptr<Derived>>(DerivedAFactory());
但是,这种方法存在潜在的陷阱。更稳健的解决方案涉及从 unique_ptr
unique_ptr<Derived> CastToDerived(Base* obj) { return unique_ptr<Derived>(static_cast<Derived*>(obj)); }
只要对象从 DLL 动态加载并从同一上下文释放,此转换过程就应该保持有效。但是,在不同上下文之间转移所有权时,必须注意在指针旁边提供正确的删除器。
为了增加安全性和灵活性,建议使用函数模板进行转换:
template<typename Derived, typename Base, typename Del> std::unique_ptr<Derived, Del> static_unique_ptr_cast( std::unique_ptr<Base, Del>&& p ) { auto d = static_cast<Derived *>(p.release()); return std::unique_ptr<Derived, Del>(d, std::move(p.get_deleter())); } template<typename Derived, typename Base, typename Del> std::unique_ptr<Derived, Del> dynamic_unique_ptr_cast( std::unique_ptr<Base, Del>&& p ) { if(Derived *result = dynamic_cast<Derived *>(p.get())) { p.release(); return std::unique_ptr<Derived, Del>(result, std::move(p.get_deleter())); } return std::unique_ptr<Derived, Del>(nullptr, p.get_deleter()); }
这些模板确保传递的 unique_ptr 不会无意中从调用者那里窃取,同时提供静态和动态转换选项。当已知指针是派生*而无需动态转换时,可以使用静态版本,而动态版本使用dynamic_cast执行运行时检查。
以上是如何在 C 中安全地将 `unique_ptr` 向下转换为 `unique_ptr` ?的详细内容。更多信息请关注PHP中文网其他相关文章!