[英]shared_ptr and slicing
Someone I worked with once said that shared_ptr was unsafe and would slice when casting from a derived class to a base class (ie upcasting). 我曾与之合作的人曾说过,shared_ptr是不安全的,并且会在从派生类转换为基类时进行切片(即向上转换)。 For example if there were 2 classes A and B where B derived from A, then
例如,如果有两个A和B类,其中B来自A,那么
shared_ptr<A> a(new B)
would slice. 会切片。 I pointed him to http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/shared_ptr.htm where it says
我把他指向http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/shared_ptr.htm
shared_ptr<T>
can be implicitly converted toshared_ptr<U>
wheneverT*
can be implicitly converted toU*
.只要
T*
可以隐式转换为U*
shared_ptr<T>
就可以隐式转换为shared_ptr<U>
。
implied that it's safe to use in those contexts but he didn't seem to think so. 暗示在这些情况下使用是安全的,但他似乎并不这么认为。
That someone is wrong, object slicing doesn't apply to pointers. 有人错了, 对象切片不适用于指针。 That the pointer usage is wrapped away in a
shared_ptr
doesn't change that - it doesn't do any particular magic here, it initializes an internal pointer with the value passed to its constructor. 指针用法被包装在
shared_ptr
并没有改变它 - 它在这里没有做任何特殊的魔法,它用传递给它的构造函数的值初始化一个内部指针。
Simplified it could look eg like this for the purpose of this question: 为了这个问题,简化它可能看起来像这样:
template<class T> struct ptr {
T* t;
ptr(T* t) : t(t) {}
// ...
};
You lose the static type-information of B
, yes, but nothing changes regarding the object pointed to. 你丢失了
B
的静态类型信息,是的,但是对于指向的对象没有任何变化。
Pointers are PODs (just for the record: shared_ptr
s aren't). 指针是POD(仅用于记录:
shared_ptr
不是)。
The question quotes: 问题引用:
shared_ptr can be implicitly converted to shared_ptr whenever T* can be implicitly converted to U*.
只要T *可以隐式转换为U *,shared_ptr就可以隐式转换为shared_ptr。
This is about converting from one type to another, which is different from upcasting. 这是关于从一种类型转换到另一种类型,这与向上转换不同。 There's no inheritance relationship between
shared_ptr<A>
and shared_ptr<B>
, whether or not A
derives from B
or viceversa. shared_ptr<A>
和shared_ptr<B>
之间没有继承关系,无论A
是否来自B
或反之亦然。 This is the reason why the shared_ptr
object itself doesn't slice. 这就是为什么
shared_ptr
对象本身不切片的原因。
Consider a class hierarchy A, B with no virtual destructors. 考虑没有虚拟析构函数的类层次结构A,B。
std::shared_ptr<A> a(new B);
auto a = std::make_shared<B>();
will capture B's deallocator and then will call B's destructor when needed 将捕获B的解除分配器,然后在需要时调用B的析构函数
std::shared_ptr<A> a((A*)(new B));
will do no such thing and will cause slicing problems in the pointed-to object. 不做这样的事情会导致指向对象的切片问题。
For example, using unique_ptr
has different behaviour: 例如,使用
unique_ptr
具有不同的行为:
std::unique_ptr<A> a(new B);
std::unique_ptr<A> a((A*)(new B));
will both exhibit slicing problems, while 两者都会出现切片问题
auto a = std::make_unique<B>();
won't. 惯于。
Using a plain pointer doesn't help either: 使用普通指针也无济于事:
A* a = new B{};
delete a;
is a recipe for disaster. 是一个灾难的食谱。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.