RE: [Boost-Users] Preventing Cycles with shared_ptr
Jason Winnebeck wrote:
I am converting my old network library that uses explicit memory management to use shared_ptr where appropriate. So far this has gone well but I am having problem with cycles. [...]
One could use a weak pointer in the Generator to the Listener, but then the Listener may die as soon as it is registered. That's OK, though - each time the Generator wants to use the Listener, it constructs a shared_ptr out of the weak_ptr it has. If the shared_ptr is NULL, the Generator knows the Listener has gone away, and can take the appropriate steps to unregister the Listener.
... the Listener is defined by the user. So I prefer to make the task as easy as possible on the user -- so I want to allow the user to use weak or strong references if possible so he doesn't have to worry about cycles. If you want to make things easy for the user, don't offer them a choice. Choice means complexity. Complexity is bad. Require the user to use a shared_ptr to the Generator.
-- Jim
Jim.Hyslop wrote:
Jason Winnebeck wrote:
I am converting my old network library that uses explicit memory management to use shared_ptr where appropriate. So far this has gone well but I am having problem with cycles.
[...]
One could use a weak pointer in the Generator to the Listener, but then the Listener may die as soon as it is registered.
That's OK, though - each time the Generator wants to use the Listener, it constructs a shared_ptr out of the weak_ptr it has. If the shared_ptr is NULL, the Generator knows the Listener has gone away, and can take the appropriate steps to unregister the Listener.
I'm not sure if I like that. One thing I thought was neat that the shared_ptr let me do is a "registerListener( MyLister::create() );" the create method is following the design from the FAQ of protected constructors and static create method returning a shared_ptr. That way the user doesn't need to keep references to his listeners -- only to my Connection objects (I think personally it makes more sense to store a list of connections rather than a list of connection listeners when using a network API). I wanted it so that the listeners would die when the object won't generate events, in the Connection case, when the connection is disconnected I unregister its listener. The user can have active shared_ptr to the Connection and its listener without fear of cycles. Is my thinking wrong on this?
If you want to make things easy for the user, don't offer them a choice. Choice means complexity. Complexity is bad. Require the user to use a shared_ptr to the Generator.
I always hate these choices... On one hand I want to design the API as clean and simple as possible, on the other hand developers seem to get anxious if you force design paradigms down their throat, even if they are good ones. Based on the fact my library is C++ half of the people won't use it already, multithreaded kills another half, using exceptions takes another, now using reference counting will take another ;). I've designed the library so that the user only uses the classes at the level they want (I have several layers of classes with higher layers built using code only from layers below), but I've taken the stance that I won't compromise what I consider to be proper design for fear of alienating users, but that is somewhat arrogant? Jason
participants (2)
-
Jason Winnebeck
-
Jim.Hyslop