Re: [boost] Request for consideration for my weak_ptr class

Alex Burton wrote:
Marcus wrote:
It allows my code to be free of the * pointer notation. All pointers look the same, ie shared_ptr<Foo>, scoped_ptr<Foo>, weak_ptr<Foo>
Why is that desirable?
It is desirable so that that the pointers look the same, this means that fewer mistakes when changing between pointer types as code changes. It is also desirable (at least for me) so that in my code I explicitly see the intent of the pointer. When (now simple_ptr) is used the programmers intent is to only look at the object pointed to, not to own it or share it. When a normal pointer is used, the intent is unclear.
IMHO raw pointers are excellent for showing that you're only looking. If you intend to handle ownership, you'd better wrap it in something smarter as fast as possible. :)
Yes, thats exactly how I was using raw pointers (and keeping my code free of the delete keyword). However when the code changes from Foo * to scoped_ptr<Foo> or from auto_ptr<Foo> to Foo *, it seems much more logical and consistent to change from simple_ptr<Foo> to scoped_ptr<Foo> or from auto_ptr<Foo> to simple_ptr<Foo>. It also requires slightly less key presses in my opinion, as only the name of the pointer type has to be changed, where as with raw pointers it requires edits on both sides of the type name. I suppose my point is now that C++ developers have been so clever to have written smart pointers, and that those smart pointers require a different form to the raw pointers, then to keep the language looking consistent it makes sense to get rid of the raw pointers entirely and leave them to become another relic from C that C++ programmers have access to but choose not to use.
Therefore I am a bit confused, since, most of the time, a smart_pointer class implies some form of memory management. But that's not always the case. I've seen smart-pointers used to select thread-specific data (not just boost::thread_specific_pointer, which also handles ownership) etc. Yes it is unprecedented as in usually a smart pointer does something smart. If smart pointers are pointers that do something smart then it is not one. If smart pointers are template classes with overloaded -> and * operaters then it is one.
vector<Foo> foos;
BOOST_FOREACH(weak_ptr<Foo> f,foos) { //do something with f-> }
OTOH, the for_each could use an indirect_iterator-range instead, to iterate over IFoo& instead.
Yes but that would require a change to the code.
True. It all depends where you want to put the deref-or-not logic. (either in the pointer type or in the container or in a fancy make_range-function.)
The container example is just one, there are many instances where taking a simple_ptr from a Foo object, which may change to a scoped_ptr<Foo> object, etc make this useful. Alex

Alex Burton wrote:
Yes it is unprecedented as in usually a smart pointer does something smart. If smart pointers are pointers that do something smart then it is not one.
Perhaps a more fitting name would be dumb_ptr then. :) - Michael Marcin

Christopher Diggins called this kind of pointers "unsmart pointers" in a CUJ article: http://www.ddj.com/dept/cpp/184401977 http://www.ddj.com/dept/cpp/184402003 Although it doesn't present exactly the same functionnality, it applies well to it. He is maybe not the first to put that name on that concept however. I often use the kind of pointer Alex just presented to us. However I call it ref_ptr, as I use it to make an optional reference to something. The main advantages of this dumb/unsmart pointer for me is: 1- As Alex says, to standardize the pointer interface. Some may like, some other not, but I personally like it. 2- Explicitly specify that this is a pointer without any ownership relation. With legacy code where you can have a mix of smart pointers and explicit memory managment, it can be useful. 3- Default init to null, so no more uninitialized pointers. 4- assert that the pointer is not null at * or -> Vincent Bhérer-Roy On 19-Jun-07, at 19:04, Michael Marcin wrote:
Perhaps a more fitting name would be dumb_ptr then.
:)
- Michael Marcin
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/ listinfo.cgi/boost

I'd like to add to Vincent's list: 5. Improved searchability in the same sense that it's easier to search for dumb_ptr<T> then it's to search T* (compare with reinterpret_cast<T*> and C-style (T*)) All in all I like the idea. Regards, Mårten

On 19/06/07, Alex Burton <alexibu@mac.com> wrote:
Yes, thats exactly how I was using raw pointers (and keeping my code free of the delete keyword). However when the code changes from Foo * to scoped_ptr<Foo> or from auto_ptr<Foo> to Foo *, it seems much more logical and consistent to change from simple_ptr<Foo> to scoped_ptr<Foo> or from auto_ptr<Foo> to simple_ptr<Foo>. It also requires slightly less key presses in my opinion, as only the name of the pointer type has to be changed, where as with raw pointers it requires edits on both sides of the type name.
I suppose my point is now that C++ developers have been so clever to have written smart pointers, and that those smart pointers require a different form to the raw pointers, then to keep the language looking consistent it makes sense to get rid of the raw pointers entirely and leave them to become another relic from C that C++ programmers have access to but choose not to use.
I'd take the opposite viewpoint. It's absolutely essential that shared_ptr, for example, have a different syntax than raw pointers. typedef int *myptr_t; int *p = new int; myptr_t p1 = p; p1 = new int; delete p1; p1 = p; delete p; Perfectly safe. Change myptr_t to a shared_ptr<int>, and it doesn't compile. This is a good thing, because if it did, you'd delete something twice.
Yes it is unprecedented as in usually a smart pointer does something smart. If smart pointers are pointers that do something smart then it is not one. If smart pointers are template classes with overloaded -> and * operaters then it is one.
Do you consider boost::optional a smart pointer?
The container example is just one, there are many instances where taking a simple_ptr from a Foo object, which may change to a scoped_ptr<Foo> object, etc make this useful.
Can you elaborate them? For the returning case, I don't see why returning a reference is insufficient. For the container iteration case, it seems like ptr_vector or a dereferencing iterator adapter is a much clearer method.
participants (5)
-
Alex Burton
-
Michael Marcin
-
Mårten Rånge
-
Scott McMurray
-
Vincent Bhérer-Roy