如何向下转换 std::shared_ptr?
考虑一下:(
struct SomethingThatsABase
{
virtual bool IsChildOne() const { return false; }
virtual bool IsChildTwo() const { return false; }
};
struct ChildOne : public SomethingThatsABase
{
virtual bool IsChildOne() const { return true; }
};
struct ChildTwo : public SomethingThatsABase
{
virtual bool IsChildTwo() const { return true; }
};
void SomeClientExpectingAChildOne(std::shared_ptr<ChildOne> const& ptrOne)
{
//Does stuff
}
void SomeClient(std::shared_ptr<SomethingThatsABase> const& ptr)
{
if (ptr->IsChildOne())
{
SomeClientExpectingAChildOne(ptr); //Oops.
//Hmm.. can't static_cast here, because we need a `shared_ptr` out of it.
}
}
请注意,我不能简单地执行 std::shared_ptr
,因为这样引用计数就不会在两个 shared_ptr
之间共享)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这应该有效:
This ought to work:
static_cast
的shared_ptr
等价物是static_pointer_cast
,而dynamic_cast
的shared_ptr
等价物是dynamic_pointer_cast
。The
shared_ptr
equivalent ofstatic_cast
isstatic_pointer_cast
, and theshared_ptr
equivalent ofdynamic_cast
isdynamic_pointer_cast
.从 C++11 开始,§20.10.2.2.9 ([util.smartptr C++ 标准的 .shared.cast])指定了
static_cast
、const_cast
和dynamic_cast
的等效项std::shared_ptr
如下:std::static_pointer_cast
:static_pointer_cast
需要static_cast(r.get ())
格式良好。如果r
为空,则返回空的shared_ptr
,否则返回与r
共享所有权的指针w
> 其中w.get() == static_cast(r.get())
和w.use_count() == r.use_count()
。std::const_pointer_cast
:const_pointer_cast
与static_pointer_cast
具有类似的要求和语义,只不过使用const_cast
代替 <代码>static_cast。std::dynamic_pointer_cast
:dynamic_pointer_cast
有点不同,因为它需要dynamic_cast(r.get())
才能正常工作形成并具有明确定义的语义。如果dynamic_cast(r.get())
是非零值,则返回与r
共享所有权的指针w
其中w.get() ==dynamic_cast(r.get())
和w.use_count() == r.use_count()
,否则一个空的返回shared_ptr
。std::reinterpret_pointer_cast
:对于 C++17,N3920 (于 2 月被采纳为图书馆基础知识 TS 2014)也提出了与上面类似的
std::reinterpret_pointer_cast
,只需要reinterpret_cast((U *) 0)
格式良好并返回shared_ptr(r, reinterpret_cast::element_type *>(r.get()))
。注意 N3920 还更改了其他shared_ptr
转换的措辞,并扩展了shared_ptr
以支持数组。Starting from C++11, §20.10.2.2.9 ([util.smartptr.shared.cast]) of the C++ standard specifies the equivalents of
static_cast
,const_cast
anddynamic_cast
forstd::shared_ptr
to be as follows:std::static_pointer_cast
:static_pointer_cast
requiresstatic_cast<T *>(r.get())
to be well formed. Ifr
is empty, an emptyshared_ptr<T>
is returned, otherwise returns a pointerw
sharing ownership withr
wherew.get() == static_cast<T *>(r.get())
andw.use_count() == r.use_count()
.std::const_pointer_cast
:const_pointer_cast
has similar requirements and semantics tostatic_pointer_cast
, except thatconst_cast
is used instead ofstatic_cast
.std::dynamic_pointer_cast
:dynamic_pointer_cast
is a bit different as it requiresdynamic_cast<T *>(r.get())
to be well formed and have well defined semantics. Ifdynamic_cast<T *>(r.get())
is a non-zero value, returns a pointerw
sharing ownership withr
wherew.get() == dynamic_cast<T *>(r.get())
andw.use_count() == r.use_count()
, otherwise an emptyshared_ptr<T>
is returned.std::reinterpret_pointer_cast
:For C++17, N3920 (adopted into Library Fundamentals TS in February 2014) also proposed a
std::reinterpret_pointer_cast
similar to the above, which would only requirereinterpret_cast<T *>((U *) 0)
to be well formed and returnsshared_ptr<T>(r, reinterpret_cast<typename shared_ptr<T>::element_type *>(r.get()))
. Note N3920 also changed the wording for the othershared_ptr
casts and extendedshared_ptr
to support arrays.