[英]shared_ptr and slicing
我曾与之合作的人曾说过,shared_ptr是不安全的,并且会在从派生类转换为基类时进行切片(即向上转换)。 例如,如果有两个A和B类,其中B来自A,那么
shared_ptr<A> a(new B)
会切片。 我把他指向http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/shared_ptr.htm
只要
T*
可以隐式转换为U*
shared_ptr<T>
就可以隐式转换为shared_ptr<U>
。
暗示在这些情况下使用是安全的,但他似乎并不这么认为。
有人错了, 对象切片不适用于指针。 指针用法被包装在shared_ptr
并没有改变它 - 它在这里没有做任何特殊的魔法,它用传递给它的构造函数的值初始化一个内部指针。
为了这个问题,简化它可能看起来像这样:
template<class T> struct ptr {
T* t;
ptr(T* t) : t(t) {}
// ...
};
你丢失了B
的静态类型信息,是的,但是对于指向的对象没有任何变化。
指针是POD(仅用于记录: shared_ptr
不是)。
问题引用:
只要T *可以隐式转换为U *,shared_ptr就可以隐式转换为shared_ptr。
这是关于从一种类型转换到另一种类型,这与向上转换不同。 shared_ptr<A>
和shared_ptr<B>
之间没有继承关系,无论A
是否来自B
或反之亦然。 这就是为什么shared_ptr
对象本身不切片的原因。
考虑没有虚拟析构函数的类层次结构A,B。
std::shared_ptr<A> a(new B);
auto a = std::make_shared<B>();
将捕获B的解除分配器,然后在需要时调用B的析构函数
std::shared_ptr<A> a((A*)(new B));
不做这样的事情会导致指向对象的切片问题。
例如,使用unique_ptr
具有不同的行为:
std::unique_ptr<A> a(new B);
std::unique_ptr<A> a((A*)(new B));
两者都会出现切片问题
auto a = std::make_unique<B>();
惯于。
使用普通指针也无济于事:
A* a = new B{};
delete a;
是一个灾难的食谱。
此处提供示例代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.