繁体   English   中英

shared_ptr和切片

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM