On Mon, Aug 3, 2015 at 3:40 PM, K. Frank <kfrank2...@gmail.com> wrote:
> Hello List! > > Another question, again looking at the Wt::Dbo tutorial: > > http://www.webtoolkit.eu/wt/doc/tutorial/dbo.html > > and, specifically, the example code: > > ... > /* > * A unit of work happens always within a transaction. > */ > dbo::Transaction transaction(session); > > User *user = new User(); > user->name = "Joe"; > user->password = "Secret"; > user->role = User::Visitor; > user->karma = 13; > > dbo::ptr<User> userPtr = session.add(user); > } > > I would like to check my understanding of Wt::Dbo::ptr. > > When I say "ownership" I mean, primarily, the responsibility for > memory management, in particular, calling delete. > > As I understand it it, when the local variable "userPtr" goes out > of scope (at the closing brace at the end of the example code) > delete will be called on "user" (of type User*). Is this correct? > (I understand that Wt::Dbo::ptr is a shared pointer, so that delete > will be called when the last of multiple shared pointers is destroyed, > but in this case userPtr is the only such pointer.) > > So, in my language, userPtr (together with any other shared pointers > pointing to the same object) "owns" the instance of class User pointed > to by the variable "user". Is this correct? > That matches my experience, the documentation, convention, and shared pointer semantics :-) > So, in particular, something like: > > { > User user; > user-.name = "Joe"; > // ... > dbo::ptr<User> userPtr = session.add(&user); > } > > would NOT be the right way to do this because when userPtr > goes out of scope, it would try to delete &user, (a pointer to) > an object that was not created by a call to new. (And furthermore > user's destructor would be called twice -- once by the incorrect > call to delete, and then again when user went out of scope.) > Is this correct? > Yup. > > I have a question about exception safety: What if the call to > session.add() throws? My understanding is that userPtr will > not yet have been assigned, and will therefore not be able to > delete (the object. Who then would have responsibility for calling > 'delete user;"? > > Is this issue just a simplification in the sample code and the (only?) > exception-safe way to do this would be: > > { > User *user = new User(); > > // this stuff can't throw -- true? > user->name = "Joe"; > // ... > dbo::ptr<User> userPtr((user); > > // this could throw, but userPtr ensures that user will be deleted > session.add(userPtr); > } > > Is there ever any fully exception-safe use of the original version? > > dbo::ptr<User> userPtr = session.add(&user); Excellent question. Based on the current source, it should be okay to pass a pointer to a business object even in an exceptional situation. The source is: 228 template <class C> 229 ptr<C> Session::add(C *obj) 230 { 231 ptr<C> result(obj); 232 return add(result); 233 } If Wt::Dbo::Session::add(Wt::Dbo::ptr<C>&) throws, the original object will be deleted. Of course, I can't think of many ways that session.add(&user); could be used, excepting something like User * ptr_user = new User(); User & user {*ptr_user}; session.add(&user); /*We don't own ptr_user anymore, so don't delete it!*/ Happy coding! In Christ, Aaron Laws
------------------------------------------------------------------------------
_______________________________________________ witty-interest mailing list witty-interest@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/witty-interest