代码之家  ›  专栏  ›  技术社区  ›  sashang

共享ptr和切片

  •  9
  • sashang  · 技术社区  · 14 年前

    与我共事的人曾经说过,shared\u 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 上面写着

    shared_ptr<T> 可以隐式转换为 shared_ptr<U> 无论何时 T* 可以隐式转换为 U* .

    暗示在这种情况下使用是安全的,但他似乎不这么认为。

    2 回复  |  直到 14 年前
        1
  •  12
  •   Georg Fritzsche    14 年前

    有人错了, object slicing 不适用于指针。指针用法被包装在 shared_ptr 不会改变这一点-它在这里没有任何特殊的魔力,它用传递给构造函数的值初始化一个内部指针。

    简化了,例如,就这个问题而言,它可以是这样的:

    template<class T> struct ptr {
        T* t;
        ptr(T* t) : t(t) {}
        // ...
    };
    

    您将丢失的静态类型信息 B ,是的,但指向的对象没有任何变化。

        2
  •  0
  •   Stefano Falasca    9 年前

    指针是豆荚(仅供参考: shared_ptr

    问题引述:

    这是关于从一种类型转换到另一种类型,这与向上投射不同。两者之间没有继承关系 shared_ptr<A> shared_ptr<B> ,无论是否 A B 或者维切弗萨。这就是为什么 共享\u ptr

    对象切片不能成为关注点这是不正确的

    std::shared_ptr<A> a(new B);
    auto a = std::make_shared<B>();
    

    将捕获B的deallocator,然后在需要时调用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;
    

    是一个灾难的配方。

    示例代码可用 here .