c++ - "Downcasting"unique_ptr<Base> 到 unique_ptr<Derived>

标签 c++ c++11 smart-pointers factory-pattern unique-ptr

我有一系列工厂返回unique_ptr<Base> .然而,在幕后,它们提供了指向各种派生类型的指针,即 unique_ptr<Derived> , unique_ptr<DerivedA> , unique_ptr<DerivedB>等等

给定 DerivedA : DerivedDerived : 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 中的对象来做到这一点。 ,然后使用转换原始指针并将其重新分配给另一个 unique_ptr 的函数所需的风格(release 将由调用者在调用之前显式完成):

unique_ptr<Derived> CastToDerived(Base* obj) {
    return unique_ptr<Derived>(static_cast<Derived*>(obj));
}

这是有效的,还是/会发生什么时髦的事情?


PS。更复杂的是,一些工厂驻留在运行时动态加载的 DLL 中,这意味着我需要确保生成的对象在创建时在相同的上下文(堆空间)中销毁。然后所有权的转移(通常发生在另一个上下文中)必须从原始上下文中提供一个删除器。但除了必须与指针一起提供/强制转换删除器之外,强制转换问题应该是相同的。

最佳答案

我会创建几个函数模板,static_unique_ptr_castdynamic_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 将地毯从调用者的脚下拉出来。

关于c++ - "Downcasting"unique_ptr<Base> 到 unique_ptr<Derived>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21174593/

相关文章:

c++ - Eigen 张量编译错误

c++ - 如何以最快的方式检查两个给定位置之间是否存在数字?

c++ - 为什么这个类型别名会导致编译错误(C++)?

c++ - 如何使用 boost::serialization 序列化 TAO::unbouded_basic_string_sequence<T>?

c++ - Qt 智能指针相当于 Boost::shared_ptr ?

c++ - 使用 C++ boost 属性树在多个标签上具有相同属性的 XML

C++:为智能指针的字段隐式保留右值引用

c++ - 为什么匿名 unique_ptr 值会立即被破坏

c++ - 用方法替换包装智能指针

C++创建进程时指定进程id