如何在C ++中将基本智能指针转换为派生的智能指针?

时间:2016-08-03 03:03:24

标签: c++ pointers

代码:

class Base {
    ...
};

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

问题是: 1.如果我使用Base类的智能指针来引用Derived,我之所以这样做,是因为我希望获得仅适合虚函数的动态绑定的好处。但是如果我想使用仅由派生类拥有的功能,我该怎么办? 不同类的智能指针之间的static_cast给我一个错误......

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

3 个答案:

答案 0 :(得分:4)

在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
    }
}

答案 1 :(得分:3)

使用std::dynamic_pointer_cast。如果演员表不成功,这将返回空shared_ptr

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

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

答案 2 :(得分:0)

对于智能指针本身,它取决于智能指针。指向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手动完成(对于多态基础),加上{ {1}}。

但是,release具有关联的函数std::shared_ptrstatic_pointer_castdynamic_pointer_cast,而其他智能指针可能具有同上函数 - 但这很大程度上取决于智能指针。