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

Marcus wrote:
Alex Burton wrote:
I understand there would be a collision with boost::weak_ptr, which is used for special scenarios with shared_ptr as I understand.
Hm. checked_ptr, standard_ptr, regular_ptr, simple_ptr or just raw_ptr might be better names, to avoid collisions? I agree with you. I've changed it to simple_ptr (standard_ptr, regular_ptr would be ok too), checked_ptr doesn't describe the true intent, and raw_ptr would cause confusion when speaking about actual raw pointers and instances raw_ptr.
(The concept of a weak pointer or reference is quite common when used in garbage collection, as with boost::shared_ptr, so IMHO I would avoid that in general for non-gc pointer types.)
A fair comment would be that this class actually does nothing, that a normal pointer would do and this is true. However, I find it extremely useful, and would like it considered as an addition to boost.
Good initiative. However, there seems to be some orthogonal concepts baked in here, and everyone might not want all of them at the same time, even if each one is useful on their own. Perhaps each concept could be split up (via policy classes) so that one could define checks for any pointer? The intent of the pointer is not just to check null dereferences. The check that currently throws an exception could be changed to do what scoped_ptr etc does, which is to do a debug assertion.
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.
It throws an exception if it has been default constructed or set to 0, this could probably be a debug only behaviour for efficiency, but i leave it in release code.
I find the notion of a null ptr useful. How about just checking that in operator * and -> as other boost::ptr's. I do too (though never in production code, only in test code). The check is only made as you describe.
Unless actually do want a nonnull_ptr, but that should be optional. (boost::ahared_ptr's can be
It can be used in many places a reference would be used.
I don't get this one. It's not a smart reference, a smart pointer? No it is just a non owning pointer.
It includes constructors for many smart pointer types and from a reference to the class pointed to.
Useful. However, you might want to consider a unqualified get_pointer() call to allow for any smart pointer (including my secret one that I won't show you :-). Also, less constructors. (as for get_pointer(), I believe boost::bind and others uses it to get the raw-pointer from any type, including references)
Great suggestion, ive replaced all those constructors with template<class Y> simple_ptr(const Y & y) : p(get_pointer(y)) {} and added template<class T> inline T * get_pointer(simple_ptr<T> const & p) { return p.get(); }
using namespace std;
struct IFoo { };
struct Foo : IFoo { };
vector<Foo> foos;
BOOST_FOREACH(weak_ptr<Foo> f,foos) { //do something with f-> }
vector< weak_ptr<IFoo> > weakfoos; std::copy(foos.begin(),foos.end(),back_inserter(weakfoos));
In the above code, if vector<Foo> foos was changed to vector< shared_ptr<Foo> > the code will still work perfectly with out change.
I find this really useful because often small structs become polymorphic classes (requiring shared_ptr) as code evolves.
Yup. I see where that could be useful.
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.

Alex Burton wrote:
Marcus wrote:
A fair comment would be that this class actually does nothing, that a normal pointer would do and this is true. However, I find it extremely useful, and would like it considered as an addition to boost.
Good initiative. However, there seems to be some orthogonal concepts baked in here, and everyone might not want all of them at the same time, even if each one is useful on their own. Perhaps each concept could be split up (via policy classes) so that one could define checks for any pointer?
The intent of the pointer is not just to check null dereferences. The check that currently throws an exception could be changed to do what scoped_ptr etc does, which is to do a debug assertion.
Right.
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. :) 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.
It throws an exception if it has been default constructed or set to 0, this could probably be a debug only behaviour for efficiency, but i leave it in release code.
I find the notion of a null ptr useful. How about just checking that in operator * and -> as other boost::ptr's.
I do too (though never in production code, only in test code). The check is only made as you describe.
Ok. I misunderstood and thought you wanted to disallow it being null completely. :)
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.) Cheers, /Marcus
participants (2)
-
Alex Burton
-
Marcus Lindblom