From 829869bc0f7bc3529be4f282bab576efe5458a6c Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 20 Sep 2010 18:00:14 +0200 Subject: Make result_iterator::operator* return reference Add load() version that returns the dynamically-allocated instance. --- doc/manual.xhtml | 66 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 29 deletions(-) (limited to 'doc') diff --git a/doc/manual.xhtml b/doc/manual.xhtml index 173b964..fd9875d 100644 --- a/doc/manual.xhtml +++ b/doc/manual.xhtml @@ -2056,26 +2056,30 @@ namespace odb class result_iterator { public: - typename object_traits<T>::pointer_type + T* operator-> () const; - typename object_traits<T>::pointer_type + T& operator* () const; + typename object_traits<T>::pointer_type + load (); + void load (T& x); }; } -

When you call the -> operator, the iterator - will allocate a new instance of the object class in the - dynamic memory, load its state from the returned database - state, and return the pointer to the new instance. In - case of this operator, the iterator still maintains the - ownership of the returned object and will return the - same pointer for subsequent calls until advanced to - the next object. For example:

+

When you call the * or -> operator, + the iterator will allocate a new instance of the object class + in the dynamic memory, load its state from the returned database + state, and return a reference or pointer to the new instance. The + iterator maintains the ownership of the returned object and will + return the same pointer for subsequent calls to either of these + operators until it is advanced to the next object or you call + the first overloaded variant of the load() + function (see below). For example:

   result r (db->query<person> (query::first == "John"));
@@ -2083,38 +2087,42 @@ namespace odb
   for (result::iterator i (r.begin ()); i != r.end ();)
   {
     cout << i->last () << endl; // Create an object.
-    cout << i->age () << endl;  // Use the same object.
+    person& p (*i);             // Reference to the same object.
+    cout << p.age () << endl;
     ++i;                        // Free the object.
   }
   
- -

The * operator is similar to -> - (notice that it also returns a pointer) except that it - relinquishes the ownership of the allocated object. In - fact, it is very similar to the database::load() - variant which returns a dynamically allocated instance. - Note also that subsequent calls to this operator or to - -> return the same object. The following - example shows how we can use this operator:

+

The result_iterator::load() function is similar to + database::load(). The first overloaded variant + returns a dynamically allocated instance of the current + object which you are responsible for deleting. As an optimization, + if the iterator already owns an object as result of the earlier + call to the * or -> operator, then it + relinquishes the ownership of this object and returns it instead. + This allows you to write code like this without worrying about + a double allocation:

   result r (db->query<person> (query::first == "John"));
 
   for (result::iterator i (r.begin ()); i != r.end (); ++i)
   {
-    auto_ptr p (*i);             // Create an object.
-    cout << p->last () << endl;  // Use the same object.
-    cout << i->age () << endl;   // Use the same object.
-    p.reset ();                  // Free the object.
-    cout << i->first () << endl; // Error, object was deleted.
+    if (i->last == "Doe")
+    {
+      auto_ptr p (i.load ());
+      ...
+    }
   }
   
-

The result_iterator::load() function allows - you to load the current object's state into an existing - instance. It is similar to the second overloaded variant - of the database::load() function. For example:

+

Note, however, that because of this optimization, a subsequent to + load() call to the * or -> + operator results in the allocation of a new object.

+ +

The second variant of the result_iterator::load() + function allows you to load the current object's state into an + existing instance. For example:

   result r (db->query<person> (query::first == "John"));
-- 
cgit v1.1