“downcasting”unique_ptr <Base>到unique_ptr <Derived>
我有一系列返回unique_ptr<Base>
的工厂。 然而,它们提供了指向各种派生types的指针,即unique_ptr<Derived>
, unique_ptr<DerivedA>
, unique_ptr<DerivedB>
等。
鉴于DerivedA : Derived
和Derived : Base
我们会有:
unique_ptr<Base> DerivedAFactory() { return unique_ptr<Base>(new DerivedA); }
我需要做的就是将指针从返回的unique_ptr<Base>
到某个派生级别(不一定是原来的内部级别)。 为了说明伪代码:
unique_ptr<Derived> ptr = static_cast<unique_ptr<Derived>>(DerivedAFactory());
我正在考虑通过从unique_ptr
释放对象,然后使用一个函数来转换原始指针并将其重新分配给另一个所需flavor的unique_ptr
( release
将在调用之前由调用方明确完成):
unique_ptr<Derived> CastToDerived(Base* obj) { return unique_ptr<Derived>(static_cast<Derived*>(obj)); }
这是有效的,还是会有一些质朴的事情呢?
PS。 还有一个复杂的问题,一些工厂驻留在运行时dynamic加载的DLL中,这意味着我需要确保生成的对象在创build时在相同的上下文(堆空间)中被销毁。 所有权的转移(通常发生在另一个环境中)必须从原始上下文中提供一个删除者。 但是除了必须提供/删除指针以外,投射问题应该是相同的。
我创build了几个函数模板, static_unique_ptr_cast
和dynamic_unique_ptr_cast
。 使用前者的情况下,你绝对肯定指针实际上是Derived *
,否则使用后者。
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
从呼叫者的脚下拖出地毯。