How do non-intrusive smart pointers behave in relation to inheritance and multiple inheritance?

I am using C ++. C ++ 0x using Visual Studio 2010 to be true.

Suppose I have a class Z. To make it safer to work with pointers to this class in my application, I can use smart pointers (general pointer, weak pointer) in sequence.

Now this class Z inherits from class X. Some parts of my application will work with pointers to class X, others will work with pointers to class Z.

  • Can I use smart pointers?
  • Are shared pointers shared if I have references to X and others related to Z? Is it guaranteed that destroying the last common instance pointer (whether it is std::shared_ptr<X>or std::shared_ptr<Z>) removes the instance? I am sure that if I delete std::shared_ptr<X>that the instance is saved as long as there is another one std::shared_ptr<Y>?

Now suppose I use multiple inheritance, where Z inherits from classes X and Y. Some parts of my application will work with std::shared_ptr<X>, others with std::shared_ptr<Y>and others with std::shared_ptr<Z>.

  • Can I use generic pointers this way?
  • Is it guaranteed that only the last smart pointer (regardless of whether it points to X, Y or Z) deletes the instance?

, , . std::shared_ptr<Z> std::shared_ptr<X>? ? ?

, ( std::shared_ptr std::weak_ptr ++ 0x). (, Boost) , , , .

+5
1

, , §20.9.11.2.10 [util.smartptr.shared.cast].

, :

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

, ++ 03 static_cast<>() dynamic_cast<>(). , std::shared_ptr s. , , , shared_ptr s.

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.
   }
}
+6

All Articles