1

In boost::scoped_ptr, says "It supplies a basic "resource acquisition is initialization" facility, without shared-ownership or transfer-of-ownership semantics." It is done through some non-copyable mechanism.

My question is why is there requirement for no shared-ownership?

Here is what I mean:

 template <typename T>
 class my_scoped_ptr
 {
 public:
  // constructor  implemented not shown here
  // operator*() implemented not shown here
  // operator -> implemented not shown here
  ~my_scoped_ptr()
  {
   delete my_p;
   my_p = NULL;
  }
 private:
  T * my_p;
 };


 void foo()
 {
  my_scoped_ptr<someclass> p (new someclass());
  my_scoped_ptr<someclass> q (p); // both p & q point to same my_p object
  // may be an exception is raised
 }

Ok now , regardless whether or not exception is raised the my_p will be deleted. so, when the code get out of foo's scope ...my_scope_ptr p destructor is called, deleting my_p and setting my_p to null. Now my_scope_ptr q destructor is called again deleting my_p , which is null at this point. It seems at destruction time I could care less whether a remaining copied pointer is pointing to a valid object.

So, why would I need to care that my_scoped_ptr should not be copyable? I don't see any harm of a ptr being copyable, if the ptr takes care of deleting the object pointed to , once it exits the scope. ??!!

thassan
  • 391
  • 3
  • 15
  • 2
    "which is null at this point" How did its member variable get updated? That's your answer. It's possible (see `shared_ptr`), but at a non-zero cost. And that's why there's at least two smart pointer types: one for simple no-overhead, and one for shared with-overhead. – GManNickG Oct 03 '13 at 21:26
  • 1
    `p.my_p` and `q.my_p` are two different variables, so setting one of them to NULL will not change the other. – green lantern Oct 03 '13 at 22:03
  • hmm; @GManNickG @green lantern I am bit confused here. What happens if I only do `delete my_p` and DO NOT set `my_p=NULL`.So, since I did not specify a copy/assignment constructor, compiler will provide miranda copy , which will do a shallow copy. After which both `p.my_p` and `q.my_p` points to the same bits of info. Now if I do `delete p.my_p` I am effectively deleting what my_p points to. so `q.my_p` is left dangling I agree to that. But its left dangling at the point when my function is going out of scope. Why not implement this solution..?? – thassan Oct 04 '13 at 00:44

1 Answers1

1
void foo()
 {
  my_scoped_ptr<someclass> p (new someclass());
  my_scoped_ptr<someclass> q (p); // both p & q point to same my_p object
  // may be an exception is raised
 }

As the function ends (return or throw) and q goes out of scope, the destructor for q will delete the someclass object. Then immediately afterward, p goes out of scope and its destructor will delete the someclass object again.

It is not valid to delete the same pointer twice! (unless new happened to return it again in the meantime).

[ And if any C++ implementation tried to make it valid, it would either have to link together all raw pointers with the same value (which is what shared_ptr is for), or else keep track of what addresses have been deleted, which means they're still using memory of some sort and not really freed up. ]

aschepler
  • 70,891
  • 9
  • 107
  • 161