C++ 如何向下转换 std::shared_ptr ?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6795629/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does one downcast a std::shared_ptr?
提问by Billy ONeal
Consider:
考虑:
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.
}
}
(Note that I can't simply do a std::shared_ptr<ChildOne>(static_cast<ChildOne*>(ptr.get()))
, because then the reference counts don't get shared between the two shared_ptr
s)
(请注意,我不能简单地执行 a std::shared_ptr<ChildOne>(static_cast<ChildOne*>(ptr.get()))
,因为那样引用计数不会在两个shared_ptr
s之间共享)
回答by mwigdahl
This ought to work:
这应该有效:
if (ptr->IsChildOne())
{
SomeClientExpectingAChildOne(std::static_pointer_cast<ChildOne>(ptr));
}
回答by Joel
The shared_ptr
equivalent of static_cast
is static_pointer_cast
, and the shared_ptr
equivalent of dynamic_cast
is dynamic_pointer_cast
.
该shared_ptr
当量static_cast
是static_pointer_cast
,与shared_ptr
等效的dynamic_cast
是dynamic_pointer_cast
。
回答by jotik
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
and dynamic_cast
for std::shared_ptr
to be as follows:
从 C++11 开始,C++ 标准的 §20.10.2.2.9 ( [util.smartptr.shared.cast]) 指定static_cast
,const_cast
和dynamic_cast
for的等效项std::shared_ptr
如下:
std::static_pointer_cast
:
std::static_pointer_cast
:
template <class T, class U>
shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r) noexcept;
static_pointer_cast
requires static_cast<T *>(r.get())
to be well formed. If r
is empty, an empty shared_ptr<T>
is returned, otherwise returns a pointer w
sharing ownership with r
where w.get() == static_cast<T *>(r.get())
and w.use_count() == r.use_count()
.
static_pointer_cast
需要static_cast<T *>(r.get())
很好地形成。如果r
为空,shared_ptr<T>
则返回空,否则返回w
与r
wherew.get() == static_cast<T *>(r.get())
和共享所有权的指针w.use_count() == r.use_count()
。
std::const_pointer_cast
:
std::const_pointer_cast
:
template <class T, class U>
shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r) noexcept;
const_pointer_cast
has similar requirements and semantics to static_pointer_cast
, except that const_cast
is used instead of static_cast
.
const_pointer_cast
与 具有相似的要求和语义static_pointer_cast
,除了const_cast
使用 代替static_cast
。
std::dynamic_pointer_cast
:
std::dynamic_pointer_cast
:
template <class T, class U>
shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r) noexcept;
dynamic_pointer_cast
is a bit different as it requires dynamic_cast<T *>(r.get())
to be well formed and have well defined semantics. If dynamic_cast<T *>(r.get())
is a non-zero value, returns a pointer w
sharing ownership with r
where w.get() == dynamic_cast<T *>(r.get())
and w.use_count() == r.use_count()
, otherwise an empty shared_ptr<T>
is returned.
dynamic_pointer_cast
有点不同,因为它需要dynamic_cast<T *>(r.get())
格式良好并具有明确定义的语义。如果dynamic_cast<T *>(r.get())
是非零值,则返回w
与r
wherew.get() == dynamic_cast<T *>(r.get())
和共享所有权的指针w.use_count() == r.use_count()
,否则shared_ptr<T>
返回空值。
std::reinterpret_pointer_cast
:
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 require reinterpret_cast<T *>((U *) 0)
to be well formed and returns shared_ptr<T>(r, reinterpret_cast<typename shared_ptr<T>::element_type *>(r.get()))
. Note N3920 also changed the wording for the other shared_ptr
casts and extended shared_ptr
to support arrays.
对于 C++17,N3920(2014 年 2 月被采纳到 Library Fundamentals TS中)也提出了std::reinterpret_pointer_cast
与上述类似的方法,只需要reinterpret_cast<T *>((U *) 0)
格式良好并返回shared_ptr<T>(r, reinterpret_cast<typename shared_ptr<T>::element_type *>(r.get()))
。注意 N3920 还更改了其他类型shared_ptr
转换的措辞并扩展shared_ptr
为支持数组。