代码:
class Base {
...
};
class Derived : public Base {
void OnlyOwnedByDerived{
...
}
};
问题是:
1.如果我使用Base类的智能指针来引用Derived,我之所以这样做,是因为我希望获得仅适合虚函数的动态绑定的好处。但是如果我想使用仅由派生类拥有的功能,我该怎么办?
不同类的智能指针之间的static_cast
给我一个错误......
答案 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_cast
或dynamic_cast
手动完成(对于多态基础),加上{ {1}}。
但是,release
具有关联的函数std::shared_ptr
,static_pointer_cast
和dynamic_pointer_cast
,而其他智能指针可能具有同上函数 - 但这很大程度上取决于智能指针。