|
View:
New views
7 Messages
—
Rating Filter:
Alert me
|
|
|
RFC - lifetime managementI'd love to get some feedback on a tiny utility I've been thinking about.
I oftenly create small objects which I just want to keep alive as long as some other object exists. It is often RAII objects, but many other types of small classes fall into this category. A simple "user heap" could take ownership of such instances and delay deletion until itself is deleted. The basic interface of - let's call it heap - would look like this: template<class T> T& heap::put(T*); Example usage: boost::shared_ptr<SomeView> view; // Keep controller alive while view exits view->get_heap().put(new SomeController(*view)); For classes with loads of RAII object members, usage could look like this: class Foo { Foo() { keep_alive_.put(new RAIIBar(...)); keep_alive_.put(new RAIIWhatever(...)); } private: heap keep_alive_; }; Support should be added for putting shared_ptrs and auto_ptrs. I have a wide variety of naming suggestions and an extended interface for premature deletion but I'll save those for a later post. What do you think? Please give me your thoughts. Johan _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: RFC - lifetime managementHi,
Johan Torp schrieb: > A simple "user heap" could take ownership of such instances and delay > deletion until itself is deleted. The basic interface of - let's call > it heap - would look like this: That would be very similar to a ptr_* container that assumes ownership of the object, with a common base class for all the objects to facilitate destruction. Simon _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: RFC - lifetime managementGlad to get some response :) Requiring a common base class/interface is a huge demand. This would couple client code a lot for the sake of such a small utility and it wouldn't be directly compatible with already existing classes. The proposed "heap" has very different semantics compared to a container. Once you put something in the heap you never want to access it again. All you want to achieve is delayed and synchronized destruction. You can achieve similar functionality using a std::vector<boost::any> in which you insert boost::shared_ptrs. The syntax is a lot worse though and more importantly, more difficult to understand. Compare: std::vector<boost::any> keep_alive; // Always use named smart ptrs boost::shared_ptr<boost::signals::scoped_connection> connection(new boost::signals::scoped_connection(signal, slot)); keep_alive.push_back(connection); boost::heap keep_alive; keep_alive.put(new boost::signals::scoped_connection(signal, slot)); In the latter case we clearly signal something - we're not interested in the connection variable, only it's lifetime. Johan |
|
|
Re: RFC - lifetime management> For classes with loads of RAII object members, usage could > look like this: > > class Foo { > Foo() { > keep_alive_.put(new RAIIBar(...)); > keep_alive_.put(new RAIIWhatever(...)); > } > private: > heap keep_alive_; > }; To me, that sounds very much like a std::vector<boost:shared_ptr<void> >: typedef std::vector<boost::shared_ptr<void> > heap; class Foo { Foo() { keep_alive_.push_back(boost::shared_ptr<RAIIBar>(new RAIIBar(...))); keep_alive_.push_back(boost::shared_ptr<RAIIWhatever>(new RAIIWhatever(...))); } private: heap keep_alive_; }; Does this do what you intended? With a bit of syntactic sugar, it would be possible to avoid the intermediate shared_ptr type, probably. I consider all real work already done. > Support should be added for putting shared_ptrs and > auto_ptrs. You get this for free with the above. > I have a wide variety of naming suggestions and an > extended interface for premature deletion but I'll save those > for a later post. keep_alive_.erase(keep_alive_.begin()+n); Should do that. Again, some syntactic sugar might help. Is that what you thought about? Yours, Martin. -- Dr. Martin Schulz (schulz@...) Software Engineer Synopsys GmbH Karl-Hammerschmidt-Str. 34 D-85609 Dornach, Germany Munich office: +49 (89) 993-20203 Home office: +49 (721) 6099511 http://www.synopsys.com _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: RFC - lifetime managementYes that's basically it! I often create std::vector<boost::any> containing boost:shared_ptrs. Using std::vector<boost::shared_ptr<void> > is clearer and lessens the need for this utility class a bit. Still, the heap class is even more clear, easier to use and easier to reason about. I see the following benefits over std::vector<boost::shared_ptr<void> >: 1. More informative class and method names 2. You can't access anything put in the heap through the heap. This makes code analysis a lot easier. For instance, using heap.put(new Foo) you are sure noone can access the Foo instance at all. 3. There is no way to delete something in a heap or clear it so you are sure what's put will remain alive as long as the heap. (I no longer believe premature deletion is good idea). Heaps should be non-copyable, vectors aren't. 4. Because of 2 & 3 suitable classes (such as display list nodes) can expose a get_heap-method without risking the class's clients affecting each other or the instance. 5. Raw pointers can be handled more efficiently than shared_ptrs 6. Better syntax. Repeating a long type name twice as with boost shared_ptr can be tedious Still I'm not sure if these points are enough to motivate a new utility class. It's not exactly a killer app, even though I find it very useful in MVC architectures (linking controllers life time to views) and classes with lots of RAII members. What do you think? Thanks for your input! /Johan |
|
|
Re: RFC - lifetime management> Still, the heap class is even more clear, easier to use and
> easier to reason about. > I see the following benefits over > std::vector<boost::shared_ptr<void> >: > > 1. More informative class and method names Well, the name heap makes me think of a certain kind of memory management system. Probably a name like Keepalive_bucket would be clearer? > Heaps should be non-copyable, vectors aren't. Ok, that is a design choice and clearly influences the semantic. > 5. Raw pointers can be handled more efficiently than shared_ptrs But think of it - if that pointed-to object is in use by some other means, it would be destroyed by the heap destructor nevertheless. Using shared pointers, the pointed-to objects are kept alive as long as either the heap lives or as long they are used, whatever is longer. > 6. Better syntax. Repeating a long type name twice as with > boost shared_ptr can be tedious Yes, I already noted that. > Still I'm not sure if these points are enough to motivate a > new utility class. It's not exactly a killer app, even though > I find it very useful in MVC architectures (linking > controllers life time to views) and classes with lots of RAII > members. What do you think? If ist helpfull to you, then go ahead and use & improve it. An (untested) wrapper class I would start with would be something like: class Keepalive: private boost::noncopyable { Std::vector< boost::shared_ptr<void> > v; public: template <typename T> void put(boost::shared_ptr<T> p) { v.push_back(p); }; template <typename T> void put(std::auto_ptr<T>& p) { v.push_back(boost::shared_ptr<T>(p)); }; template <typename T> void put(T *p) { v.push_back(boost::shared_ptr<T>(p)); }; }; Does that solve your needs? -- Dr. Martin Schulz (schulz@...) Software Engineer Synopsys GmbH Karl-Hammerschmidt-Str. 34 D-85609 Dornach, Germany Munich office: +49 (89) 993-20203 Home office: +49 (721) 6099511 http://www.synopsys.com _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: RFC - lifetime management>> 1. More informative class and method names
> >Well, the name heap makes me think of a certain kind of memory >management system. Probably a name like Keepalive_bucket would >be clearer? Yes! There are probably even better names. Names might involve manual/garbage collection, owner, life time [synchronizer], delayed/synchronized destruction/or, respirator, reaper, .. well, probably getting a bit too creative here :) I'd love more suggestions/opinions though! >> 5. Raw pointers can be handled more efficiently than shared_ptrs > >But think of it - if that pointed-to object is in use by some other >means, it would be destroyed by the heap destructor nevertheless. Creating a shared_ptr from a raw pointer has the same "problem". If users fail to realize this, they've misunderstood the whole point of the class. >An (untested) wrapper class I would start with would be something like: > >class Keepalive: private boost::noncopyable { > Std::vector< boost::shared_ptr<void> > v; >public: > template <typename T> void put(boost::shared_ptr<T> p) { >v.push_back(p); }; > template <typename T> void put(std::auto_ptr<T>& p) { >v.push_back(boost::shared_ptr<T>(p)); }; > template <typename T> void put(T *p) { >v.push_back(boost::shared_ptr<T>(p)); }; >}; > >Does that solve your needs? Yes, this is basically what the implementation I'm using today I looks like. The question is if anybody else finds it useful. Again - thanks for your input! Johan |
| Free embeddable forum powered by Nabble | Forum Help |