非侵入式智能指针在继承和多重继承方面的表现如何?

Pat*_*ick 5 smart-pointers visual-studio-2010 c++11

我正在使用C++.C++ 0x使用Visual Studio 2010是正确的.

假设我有一个类Z.为了使我的应用程序更安全地使用指向这个类的指针,我可以一直使用智能指针(共享指针,弱指针).

现在这个类Z继承自类X.我的应用程序的某些部分将使用指向类X的指针,其他部分将使用指向类Z的指针.

  • 我还能使用智能指针吗?
  • 如果我有一些引用X和其他引用Z的共享指针仍然有效吗?难道是保证最后一个共享指针实例(无论它是破坏std::shared_ptr<X>std::shared_ptr<Z>)删除实例?我确定如果我删除std::shared_ptr<X>,只要还有另一个实例就保留了实例std::shared_ptr<Y>吗?

现在假设我使用多重继承,其中Z继承自类X和Y.我的应用程序的某些部分将使用std::shared_ptr<X>,其他部分与std::shared_ptr<Y>其他部分一起使用std::shared_ptr<Z>.

  • 我还能用这种方式使用共享指针吗?
  • 是否仍然保证只有最后一个智能指针(无论它指向X,Y还是Z)都会删除实例?

顺便说一下,我怎样才能安全地将一个智能指针投射到另一个,例如施放std::shared_ptr<Z>std::shared_ptr<X>?这有用吗?这是允许的吗?

请注意,我明确地引用了非侵入式指针(作为新的std::shared_ptrstd::weak_ptr在C++ 0x中).当使用侵入式指针(如Boost)时,它可能有效,因为实例本身负责保持计数器.

def*_*ode 6

是的,标准§20.9.11.2.10[util.smartptr.shared.cast]支持这一点.

您需要的工具是:

  • std::static_pointer_cast<>()
  • std::dynamic_pointer_cast<>()

他们有相同的语义他们的C++ 03计数器部分static_cast<>()dynamic_cast<>().一个区别是他们只在std::shared_ptrs上工作.只是为了详细,他们按照您的期望行事并正确地分享原始和新演员之间的引用计数shared_ptr.

struct X { virtual ~X(){} };
struct Y : public X {};
struct Z : public X {};

int main()
{
   {
      //C++03
      X* x = new Z;
      Z* z = dynamic_cast<Z*>(x);
      assert(z);
      x = new Y;
      z = dynamic_cast<Z*>(x);
      assert(!z);
      z = static_cast<Z*>(x);
      assert(z); //EVIL!!!
   }

   {
      //C++0x
      std::shared_ptr<X> x{new Z};
      std::shared_ptr<Z> z{std::dynamic_pointer_cast<Z>(x)};
      assert(z);
      x = std::make_shared<Y>();
      z = std::dynamic_pointer_cast<Z>(x);
      assert(!z);
      z = std::static_pointer_cast<Z>(x);
      assert(z); //EVIL!!!

      // reference counts work as expected.
      std::shared_ptr<Y> y{std::static_pointer_cast<Y>(x)};
      assert(y);

      std::weak_ptr<Y> w{y};
      assert(w.expired());

      y.reset();
      assert(w.expired());

      x.reset();
      assert(!w.expired());      
   }
   {
      //s'more nice shared_ptr features
      auto z = std::make_shared<X>();
      std::shared_ptr<X> x{z};
      assert( z == x );
      x = z; //assignment also works.
   }
}
Run Code Online (Sandbox Code Playgroud)