【问题标题】:How can I cast a base smart pointer into the derived one in C++?如何将基本智能指针转换为 C++ 中的派生指针?
【发布时间】:2016-12-08 14:11:08
【问题描述】:

代码:

class Base {
    ...
};

class Derived : public Base {
    void OnlyOwnedByDerived{
        ...
    }
};

问题是: 1. 如果我使用基类的智能指针来引用派生类,我这样做的原因是我想获得只适合虚函数的动态绑定的好处。但是如果我想使用只属于派生类的函数,我该怎么办? static_cast 不同类的智能指针之间给我一个错误...

  1. 我能想到的最直接的方法是使用原始指针而不是智能指针...

【问题讨论】:

  • 接近投票者应该注意这个问题与shared_ptr无关。没有提到这个词。

标签: c++ pointers


【解决方案1】:

在 C++11 中,有 dynamic_pointer_cast

你可以使用的:

void func(std::shared_ptr<Base> b){
    b->VirtualBaseFunction();
    if(auto d = dynamic_pointer_cast<Derived>(b)){
         d->DerivedSpecificFunction():
         ....more code
    }
}

【讨论】:

    【解决方案2】:

    通过使用std::dynamic_pointer_cast。如果转换不成功,这将返回一个空的 shared_ptr

    如果您不希望在返回的派生指针之间共享所有权,您也可以直接在智能指针管理的指针上使用dynamic_cast

    smart_ptr_type<Base> x = ...;
    auto* derived = dynamic_cast<Derived*>(x.get());
    

    【讨论】:

    • 我没有看到仅限于 shared_ptr 的约束;我什至没有看到它被提及。因此,就问题而言,这充其量只是一个评论。在shared_ptr的情况下...
    • 因为没有足够的信息,我不得不做出一些假设。由于标准库中的所有智能指针类型都可以转换为shared_ptr,因此可以认为是“最小公分母”。如果他们正在使用 boost,那么这应该为他们提供足够的信息来定位 boost::dynamic_pointer_cast。欢迎您询问更具体的信息并自己回答问题。
    【解决方案3】:

    对于智能指针本身,它取决于智能指针。指向Derived 的智能指针不是派生自指向Base 的那种智能指针的类。 但是您可以转换原始指针。为此,如果您知道指针是派生类型,则您有 static_cast,当您不知道(或只是希望检查)并且基类是多态时,您有 dynamic_cast

    注意:如果原始指针被向下转换然后用于构造新的智能指针,则所有权假设可能会被打破。对于这种情况,应该首先释放原始智能指针的所有权。通常这是一个名为 release 的成员函数。

    例如:

    #include <iostream>
    #include <memory>
    
    struct Base
    {
        int x;
    };
    
    struct Derived
        : Base
    {
        void foo() const { std::cout << x << "\n"; }
        Derived( int const value ): Base{ value } {}
    };
    
    auto main()
        -> int
    {
        using std::unique_ptr;
        unique_ptr<Base> p_base{ new Derived{ 42 } };
    
        #ifdef CHECK
            unique_ptr<Derived> p_directly_converted{ p_base };     // !Nyet
        #endif
    
        unique_ptr<Derived> p_derived{
            static_cast<Derived*>( p_base.release() )
            };
        p_derived->foo();
    }
    

    std::unique_ptr 没有执行此向下转换的关联函数,因此必须通过static_castdynamic_cast(对于多态基)以及release 手动完成。

    但是,std::shared_ptr 具有关联的函数 static_pointer_castdynamic_pointer_castconst_pointer_cast,并且其他智能指针可能具有同上函数 - 但这在很大程度上取决于智能指针。

    【讨论】:

      猜你喜欢
      • 2013-09-23
      • 2011-08-14
      • 1970-01-01
      • 2016-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-14
      相关资源
      最近更新 更多